Merge pull request #317 from rkflx/pr/reuse-shortcut-translations

Combine and reuse translations for keyboard shortcuts
This commit is contained in:
Norbert Renner 2020-06-22 16:28:44 +02:00 committed by GitHub
commit fa59a44a5e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 172 additions and 83 deletions

View file

@ -48,9 +48,9 @@ docker-compose up serve
### How internationalization works
BRouter is translated using [i18next](https://www.i18next.com/) library, via command `gulp i18next`. It extracts translatable elements into `locales/en.json` file (English version).
BRouter is translated using [i18next](https://www.i18next.com/) library, via command `gulp i18next`. It extracts translatable elements into `locales/en.json` file (English version). (Note that unused translation keys or keys not referenced in `keys.js` might get removed automatically. Make sure to commit any changes first before running this, and only amend the previous commit after checking the diff carefully.)
As soon as this file is modified, it must be uploaded to Transifex (manually) with the command `yarn push-transifex`.
As soon as this file is modified, it must be uploaded by the maintainers to Transifex (manually) with the command `yarn push-transifex`.
Anyone can then translate BRouter directly on [Transifex](https://www.transifex.com/openstreetmap/brouter-web/) platform.

View file

@ -61,7 +61,8 @@
role="button"
aria-haspopup="true"
aria-expanded="false"
data-i18n="[title]navbar.export-tooltip"
data-i18n="[title]keyboard.generic-shortcut"
data-i18n-options='{ "action": "$t(navbar.export-tooltip)", "key": "X" }'
title="Export route"
>
<span class="fa fa-lg fa-cloud-download" aria-hidden="true"> </span>
@ -79,6 +80,12 @@
aria-haspopup="true"
aria-expanded="false"
data-i18n="[title]navbar.load.tooltip"
data-i18n-options='{
"tracksAction": "$t(navbar.load.tracks)",
"tracksKey": "O",
"nogosAction": "$t(navbar.load.nogos)",
"nogosKey": "$t(keyboard.shift)+O"
}'
title="Load route"
>
<span class="fa fa-lg fa-cloud-upload" aria-hidden="true"> </span>
@ -113,7 +120,8 @@
</div>
<div
class="nav-item"
data-i18n="[title]about.tooltip"
data-i18n="[title]keyboard.generic-shortcut"
data-i18n-options='{ "action": "$t(about.tooltip)", "key": "H" }'
title="Show more information about BRouter-Web"
>
<a class="nav-link" href="#" data-toggle="modal" data-target="#about"
@ -314,7 +322,7 @@
updated daily, see dates of
<a href="https://brouter.de/brouter/segments4/" target="_blank">data files</a>.
</p>
<p data-i18n="[html]about.details">
<p id="aboutLinks" data-i18n="[html]about.details">
<i><a href="{{privacyPolicyUrl}}" target="_blank">Privacy Policy</a></i
>,
<i
@ -709,7 +717,12 @@
<a
href="#tab_layers_control"
role="tab"
data-i18n="[title]sidebar.layers.tooltip"
data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.layers.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Select layers"
>
<!--
@ -738,7 +751,12 @@
<a
href="#tab_itinerary"
role="tab"
data-i18n="[title]sidebar.itinerary.tooltip"
data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.itinerary.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Show Itinerary"
><i class="fa fa-map-signs"></i
></a>
@ -747,7 +765,12 @@
<a
href="#tab_profile"
role="tab"
data-i18n="[title]sidebar.customize-profile.tooltip"
data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.customize-profile.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Customize profile"
><i class="fa fa-wrench"></i
></a>
@ -756,7 +779,12 @@
<a
href="#tab_data"
role="tab"
data-i18n="[title]sidebar.data.tooltip"
data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.data.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Show detailed route data table"
><i class="fa fa-table"></i
></a>
@ -765,7 +793,12 @@
<a
href="#tab_statistics"
role="tab"
data-i18n="[title]sidebar.analysis.tooltip"
data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.analysis.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Analyse route"
><i class="fa fa-pie-chart"></i
></a>
@ -1073,7 +1106,8 @@
id="elevation-btn"
aria-expanded="false"
aria-label="Toggle elevation chart"
data-i18n="[title]footer.elevation-chart"
data-i18n="[title]keyboard.generic-shortcut"
data-i18n-options='{ "action": "$t(footer.elevation-chart)", "key": "E" }'
title="Toggle elevation chart"
>
<span class="fa fa-area-chart"></span>

View file

@ -24,8 +24,8 @@ BR.Map = {
if (BR.Util.getResponsiveBreakpoint() >= '3md') {
L.control
.zoom({
zoomInTitle: i18next.t('map.zoomInTitle'),
zoomOutTitle: i18next.t('map.zoomOutTitle')
zoomInTitle: i18next.t('keyboard.generic-shortcut', { action: '$t(map.zoomInTitle)', key: '+' }),
zoomOutTitle: i18next.t('keyboard.generic-shortcut', { action: '$t(map.zoomOutTitle)', key: '-' })
})
.addTo(map);
}
@ -105,7 +105,7 @@ BR.Map = {
var locationControl = L.control
.locate({
strings: {
title: i18next.t('map.locate-me')
title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.locate-me)', key: 'L' })
},
icon: 'fa fa-location-arrow',
iconLoading: 'fa fa-spinner fa-pulse'

View file

@ -48,7 +48,7 @@ BR.RoutingOptions = L.Evented.extend({
// append shortcut text to tooltip
var button = $('#profile-alternative-form button')[0];
button.title = button.title + i18next.t('navbar.profile-tooltip');
button.title = button.title + i18next.t('navbar.profile-tooltip', { key: 'G' });
},
getOptions: function() {

View file

@ -46,7 +46,10 @@
search = new BR.Search();
map.addControl(search);
$('#map .leaflet-control-geocoder > button')[0].title = i18next.t('map.geocoder');
$('#map .leaflet-control-geocoder > button')[0].title = i18next.t('keyboard.generic-shortcut', {
action: '$t(map.geocoder)',
key: 'F'
});
router = L.bRouter(); //brouterCgi dummyRouter
@ -59,7 +62,10 @@
routing.draw(false);
control.state('activate-draw');
},
title: i18next.t('map.draw-route-stop')
title: i18next.t('keyboard.generic-shortcut', {
action: '$t(map.draw-route-stop)',
key: '$t(keyboard.escape)'
})
},
{
stateName: 'activate-draw',
@ -68,7 +74,7 @@
routing.draw(true);
control.state('deactivate-draw');
},
title: i18next.t('map.draw-route-start')
title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.draw-route-start)', key: 'D' })
}
]
});
@ -78,7 +84,7 @@
function() {
routing.reverse();
},
i18next.t('map.reverse-route')
i18next.t('keyboard.generic-shortcut', { action: '$t(map.reverse-route)', key: 'R' })
);
var deletePointButton = L.easyButton(
@ -86,7 +92,7 @@
function() {
routing.deleteLastPoint();
},
i18next.t('map.delete-last-point')
i18next.t('keyboard.generic-shortcut', { action: '$t(map.delete-last-point)', key: 'Z' })
);
deleteRouteButton = L.easyButton(
@ -94,7 +100,7 @@
function() {
clearRoute();
},
i18next.t('map.clear-route-tooltip')
i18next.t('keyboard.generic-shortcut', { action: '$t(map.clear-route)', key: '$t(keyboard.backspace)' })
);
L.DomEvent.addListener(
@ -175,8 +181,11 @@
profile.update(evt.options);
});
BR.NogoAreas.MSG_BUTTON = i18next.t('map.nogo.draw');
BR.NogoAreas.MSG_BUTTON_CANCEL = i18next.t('map.nogo.cancel');
BR.NogoAreas.MSG_BUTTON = i18next.t('keyboard.generic-shortcut', { action: '$t(map.nogo.draw)', key: 'N' });
BR.NogoAreas.MSG_BUTTON_CANCEL = i18next.t('keyboard.generic-shortcut', {
action: '$t(map.nogo.cancel)',
key: '$t(keyboard.escape)'
});
BR.NogoAreas.MSG_CREATE = i18next.t('map.nogo.click-drag');
BR.NogoAreas.MSG_DISABLED = i18next.t('map.nogo.edit');
BR.NogoAreas.MSG_ENABLED = i18next.t('map.nogo.help');
@ -305,7 +314,7 @@
BR.tracksLoader(map, layersControl, routing);
BR.routeLoader(map, layersControl, routing,pois);
BR.routeLoader(map, layersControl, routing, pois);
pois.addTo(map);
routingPathQuality.addTo(map);
@ -313,7 +322,7 @@
map.addControl(
new BR.OpacitySliderControl({
id: 'route',
title: i18next.t('map.opacity-slider'),
title: i18next.t('map.opacity-slider-shortcut', { action: '$t(map.opacity-slider)', key: 'M' }),
muteKeyCode: 77, // m
callback: L.bind(routing.setOpacity, routing)
})
@ -456,8 +465,9 @@
}
},
function(err, t) {
jqueryI18next.init(i18next, $);
$('html').localize({
jqueryI18next.init(i18next, $, { useOptionsAttr: true });
$('html').localize();
$('#aboutLinks').localize({
privacyPolicyUrl: BR.conf.privacyPolicyUrl || 'https://brouter.de/privacypolicy.html'
});

View file

@ -25,7 +25,7 @@ BR.PoiMarkers = L.Control.extend({
onClick: function() {
self.draw(true);
},
title: i18next.t('map.draw-poi-start')
title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.draw-poi-start)', key: 'P' })
},
{
stateName: 'deactivate-poi',
@ -33,7 +33,10 @@ BR.PoiMarkers = L.Control.extend({
onClick: function() {
self.draw(false);
},
title: i18next.t('map.draw-poi-stop')
title: i18next.t('keyboard.generic-shortcut', {
action: '$t(map.draw-poi-stop)',
key: '$t(keyboard.escape)'
})
}
]
}).addTo(map);

View file

@ -250,7 +250,7 @@ BR.routeLoader = function(map, layersControl, routing, pois) {
if (!this._options.format) this._options.format = trackFile.name.split('.').pop();
const reader = new FileReader();
var reader = new FileReader();
reader.onload = L.bind(this.processFile, this);
reader.readAsText(trackFile);

View file

@ -21,7 +21,7 @@ BR.RoutingPathQuality = L.Control.extend({
this.providers = {
incline: {
title: i18next.t('map.route-quality-incline'),
title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-incline)', key: 'C' }),
icon: 'fa-line-chart',
provider: new HotLineQualityProvider({
hotlineOptions: {
@ -48,7 +48,7 @@ BR.RoutingPathQuality = L.Control.extend({
})
},
altitude: {
title: i18next.t('map.route-quality-altitude'),
title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-altitude)', key: 'C' }),
icon: 'fa-area-chart',
provider: new HotLineQualityProvider({
hotlineOptions: {
@ -61,7 +61,7 @@ BR.RoutingPathQuality = L.Control.extend({
})
},
cost: {
title: i18next.t('map.route-quality-cost'),
title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-cost)', key: 'C' }),
icon: 'fa-usd',
provider: new HotLineQualityProvider({
hotlineOptions: {

View file

@ -123,24 +123,24 @@ BR.Sidebar = L.Control.Sidebar.extend({
_keydownListener: function(e) {
if (BR.Util.keyboardShortcutsAllowed(e) && e.keyCode === this.options.shortcut.toggleTabs) {
if ($('#sidebarTabs > ul > li[class=active]').length) {
// sidebar is currently open
if (e.shiftKey) {
// try to find next tab
var nextTab = $('#sidebarTabs > ul > li[class=active] ~ li:not([hidden]) > a');
if (!nextTab.length) {
// wrap around to first tab
nextTab = $('#sidebarTabs > ul > li:not([hidden]) > a');
}
// switch to next or first tab
this.open(nextTab.attr('href').slice(1));
} else {
// close current tab
// sidebar is currently open, close current tab
if (!e.shiftKey) {
this.close();
}
} else {
// sidebar is currently closed, open recent or default tab
this.open(this.recentTab);
}
if (e.shiftKey) {
// try to find next tab
var nextTab = $('#sidebarTabs > ul > li[class=active] ~ li:not([hidden]) > a');
if (!nextTab.length) {
// wrap around to first tab
nextTab = $('#sidebarTabs > ul > li:not([hidden]) > a');
}
// switch to next or first tab
this.open(nextTab.attr('href').slice(1));
}
}
}
});

View file

@ -1,8 +1,8 @@
BR.stravaSegments = function(map, layersControl) {
var stravaControl = L.control
.stravaSegments({
runningTitle: i18next.t('map.strava-running'),
bikingTitle: i18next.t('map.strava-biking'),
runningTitle: i18next.t('map.strava-shortcut', { action: '$t(map.strava-running)', key: 'S' }),
bikingTitle: i18next.t('map.strava-shortcut', { action: '$t(map.strava-biking)', key: 'S' }),
loadingTitle: i18next.t('map.loading'),
stravaToken: BR.keys.strava
})

View file

@ -12,7 +12,7 @@
"details": "<i><a href=\"{{privacyPolicyUrl}}\" target=\"_blank\">Privacy Policy</a></i>, \n<i><a href=\"https://github.com/nrenner/brouter-web#credits-and-licenses\" target=\"_blank\">Credits</a></i>,\n<i><a href=\"https://github.com/nrenner/brouter-web/blob/master/CHANGELOG.md\" target=\"_blank\">Changelog</a></i> and\n<i><a href=\"https://github.com/nrenner/brouter-web#readme\" target=\"_blank\">more info</a></i> on the client.",
"support": "General discussions/questions, support",
"title": "About",
"tooltip": "Show more information about Brouter-Web (H key)"
"tooltip": "Show more information about Brouter-Web"
},
"credits": {
"brouter": "BRouter",
@ -42,7 +42,7 @@
"ascend": "Ascend",
"cost": "Cost",
"distance": "Distance",
"elevation-chart": "Toggle elevation chart (E key)",
"elevation-chart": "Toggle elevation chart",
"energy-per-100km": "Energy per 100 km",
"hours": "hours",
"hours-abbrev": "h",
@ -58,6 +58,12 @@
"total-energy": "Total Energy",
"travel-time": "Travel time"
},
"keyboard": {
"backspace": "Backspace",
"escape": "Escape",
"generic-shortcut": "{{action}} ({{key}} key)",
"shift": "Shift"
},
"layers": {
"add-base": "Add base layer",
"add-overlay": "Add overlay",
@ -82,19 +88,18 @@
"attribution-osm-long": "OpenStreetMap contributors",
"attribution-osm-short": "OpenStreetMap",
"clear-route": "Clear route data",
"clear-route-tooltip": "Clear route data (Backspace key)",
"copyright": "Copyright",
"cycling": "Cycling",
"delete-last-point": "Delete last point (Z key)",
"delete-last-point": "Delete last point",
"delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest",
"delete-route": "Delete route",
"draw-poi-start": "Draw points of interest (P key)",
"draw-poi-stop": "Stop drawing points of interest (ESC key)",
"draw-route-start": "Draw route (D key)",
"draw-route-stop": "Stop drawing route (ESC key)",
"draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route",
"draw-route-stop": "Stop drawing route",
"enter-poi-name": "Enter Point of Interest name",
"geocoder": "Search (F key)",
"geocoder": "Search",
"geocoder-placeholder": "Search…",
"hikebike-hillshading": "Hillshading",
"hiking": "Hiking",
@ -115,25 +120,28 @@
"topo": "OpenTopoMap"
},
"loading": "Loading…",
"locate-me": "Show me where I am (L key)",
"locate-me": "Show me where I am",
"nogo": {
"cancel": "Cancel drawing no-go area (ESC key)",
"cancel": "Cancel drawing no-go area",
"click-drag": "Click and drag to draw circle",
"draw": "Draw circular no-go area (N key)",
"draw": "Draw circular no-go area",
"edit": "Click to edit",
"help": "&square; = move / resize, <span class=\"fa fa-trash-o\"></span> = delete,<br>click circle to quit editing"
},
"opacity-slider": "Set transparency of route track and markers\n(Hold M key to mute temporarily)",
"opacity-slider": "Set transparency of route track and markers",
"opacity-slider-shortcut": "{{action}}\n(Hold {{key}} key to mute temporarily)",
"preview": "Preview",
"privacy": "Privacy",
"reverse-route": "Reverse route (R key)",
"route-quality-altitude": "Altitude coding (C key to toggle)",
"route-quality-cost": "Cost coding (C key to toggle)",
"route-quality-incline": "Incline coding (C key to toggle)",
"strava-biking": "Show Strava biking segments\n(S key to toggle layer, click to reload for current area)",
"strava-running": "Show Strava running segments\n(S key to toggle layer, click to reload for current area)",
"zoomInTitle": "Zoom in (+ key)",
"zoomOutTitle": "Zoom out (- key)"
"reverse-route": "Reverse route",
"route-quality-altitude": "Altitude coding",
"route-quality-cost": "Cost coding",
"route-quality-incline": "Incline coding",
"route-quality-shortcut": "{{action}} ({{key}} key to toggle)",
"strava-biking": "Show Strava biking segments",
"strava-running": "Show Strava running segments",
"strava-shortcut": "{{action}}\n({{key}} key to toggle layer, click to reload for current area)",
"zoomInTitle": "Zoom in",
"zoomOutTitle": "Zoom out"
},
"modal": {
"close": "Close"
@ -147,12 +155,12 @@
"third": "3rd alternative"
},
"export": "Export",
"export-tooltip": "Export route (X key)",
"export-tooltip": "Export route",
"load": {
"nogos": "No-go areas",
"nogos": "Load no-go areas",
"title": "Load",
"tooltip": "Load tracks (O key)\nLoad No-go areas (Shift+O)",
"tracks": "Tracks"
"tooltip": "{{tracksAction}} ({{tracksKey}} key)\n{{nogosAction}} ({{nogosKey}})",
"tracks": "Load tracks"
},
"profile": {
"car-eco": "Car (economic)",
@ -176,7 +184,7 @@
"vm-forum-liegerad-schnell": "Recumbent bike (fast)",
"vm-forum-velomobil-schnell": "Velomobile (fast)"
},
"profile-tooltip": "\n(G key to switch)"
"profile-tooltip": "\n({{key}} key to switch)"
},
"sidebar": {
"analysis": {
@ -192,20 +200,20 @@
"unknown": "Unknown"
},
"title": "Analysis",
"tooltip": "Analyse route\n(T key to toggle, Shift+T to switch to next tab)"
"tooltip": "Analyse route"
},
"customize-profile": {
"title": "Customize profile",
"tooltip": "Customize profile\n(T key to toggle, Shift+T to switch to next tab)"
"tooltip": "Customize profile"
},
"data": {
"sync-map": "Synchronize map",
"title": "Data",
"tooltip": "Show detailed route data table\n(T key to toggle, Shift+T to switch to next tab)"
"tooltip": "Show detailed route data table"
},
"itinerary": {
"title": "Itinerary",
"tooltip": "Show itinerary\n(T key to toggle, Shift+T to switch to next tab)"
"tooltip": "Show itinerary"
},
"layers": {
"category": {
@ -232,7 +240,7 @@
"type": "Type"
},
"title": "Layers",
"tooltip": "Select layers\n(T key to toggle, Shift+T to switch to next tab)"
"tooltip": "Select layers"
},
"profile": {
"apply": "Apply",
@ -242,14 +250,14 @@
"options": "Options",
"placeholder": "Write your custom profile here.",
"profile": "Profile"
}
},
"tab-tooltip": "{{action}}\n({{toggleKey}} key to toggle, {{switchKey}} to switch to next tab)"
},
"title": "BRouter web client",
"trackasroute": {
"explainpoi": "(show waypoints as POI's)",
"explaintracklayer": "(show Track as separate Layer)",
"file": "Trackfile",
"fromext": "from file extension",
"fuzziness": "fuzzines",
"pleasewait": "Please wait!",
"showpois": "POI's",

View file

@ -1,4 +1,33 @@
// this file contains translatable keys that are dynamic / not visible by i18n extractor tool
i18next.t('about.tooltip');
i18next.t('footer.elevation-chart');
i18next.t('keyboard.backspace');
i18next.t('keyboard.escape');
i18next.t('keyboard.shift');
i18next.t('map.delete-last-point');
i18next.t('map.draw-poi-start');
i18next.t('map.draw-poi-stop');
i18next.t('map.draw-route-start');
i18next.t('map.draw-route-stop');
i18next.t('map.geocoder');
i18next.t('map.locate-me');
i18next.t('map.nogo.cancel');
i18next.t('map.nogo.draw');
i18next.t('map.opacity-slider');
i18next.t('map.reverse-route');
i18next.t('map.route-quality-altitude');
i18next.t('map.route-quality-cost');
i18next.t('map.route-quality-incline');
i18next.t('map.strava-biking');
i18next.t('map.strava-running');
i18next.t('map.zoomInTitle');
i18next.t('map.zoomOutTitle');
i18next.t('navbar.export-tooltip');
i18next.t('navbar.profile.car-eco');
i18next.t('navbar.profile.car-fast');
i18next.t('navbar.profile.car-test');
@ -20,11 +49,16 @@ i18next.t('navbar.profile.trekking-steep');
i18next.t('navbar.profile.vm-forum-liegerad-schnell');
i18next.t('navbar.profile.vm-forum-velomobil-schnell');
i18next.t('sidebar.analysis.tooltip');
i18next.t('sidebar.customize-profile.tooltip');
i18next.t('sidebar.data.tooltip');
i18next.t('sidebar.itinerary.tooltip');
i18next.t('sidebar.layers.category.base-layers', 'Base layers');
i18next.t('sidebar.layers.category.worldwide-international', 'Worldwide international');
i18next.t('sidebar.layers.category.worldwide-monolingual', 'Worldwide monolingual');
i18next.t('sidebar.layers.category.country', 'Country');
i18next.t('sidebar.layers.category.europe', 'Europe');
i18next.t('sidebar.layers.category.europe-monolingual', 'Europe monolingual');
i18next.t('sidebar.layers.category.country', 'Country');
i18next.t('sidebar.layers.category.overlays', 'Overlays');
i18next.t('sidebar.layers.category.worldwide', 'Worldwide');
i18next.t('sidebar.layers.category.worldwide-international', 'Worldwide international');
i18next.t('sidebar.layers.category.worldwide-monolingual', 'Worldwide monolingual');
i18next.t('sidebar.layers.tooltip');