Skip to content
This repository has been archived by the owner on Jan 28, 2020. It is now read-only.

Language switcher #917

Merged
merged 5 commits into from
Jun 3, 2016
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
65 changes: 65 additions & 0 deletions candidates/static/candidates/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,71 @@
}
}

.nav-language {
display: inline-block;
font-size: 0.9em;
margin-left: 1em;
position: relative;

&:before {
position: absolute;
z-index: 0; // position behind the `select`
left: 0;
top: 50%;
margin-top: -0.1em; // vertically centre
@include css-triangle(0.3em, rgba(255, 255, 255, 0.9), top);
}

// The nav-language inputs are heavily custom styled.
// So, reset a bunch of defaults before we start.
select, input {
display: inline-block;
height: auto;
width: auto;
border: none;
background: none;
padding: 0;
margin: 0;
font-size: 1em;
line-height: 1.5em;
}

select {
position: relative;
z-index: 2; // position in front of the `:before` triangle
padding-left: 1em;
color: rgba(255, 255, 255, 0.9);

// Increase contrast on focus.
&:focus {
color: #fff;
}

// Dropdown menu options inherit things like text color
// on IE and Firefox on Windows inherit, meaning we also
// need to set a dark background color if we want the white
// text to be legible.
option {
background-color: darken($header-background-color, 5%);
}
}

select::-ms-expand {
display: none;
}

input {
background-color: rgba(255, 255, 255, 0.9);
color: darken($header-background-color, 5%);
border-radius: 0.2em;
padding: 0.1em 0.5em;

html.js & {
display: none;
}
}
}


// A nav list component we use twice in the header.
// TODO: Make this fold away on mobile!
Expand Down
5 changes: 5 additions & 0 deletions candidates/static/js/language-switcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$(function(){
$('.js-language-switcher select').on('change', function(){
this.form.submit();
});
});
4 changes: 4 additions & 0 deletions candidates/static/js/vendor/custom.modernizr.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions candidates/tests/test_constituency_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,11 @@ def test_any_constituency_page_without_login(self):
response.mustcontain('<a href="/person/2009/tessa-jowell" class="candidate-name">Tessa Jowell</a> <span class="party">Labour Party</span>')
# There should be only one form ( person search ) on the page if you're not logged in:

# even though there is only one form on the page the list has
# two entries - one for the numeric identifier and one for the id
self.assertEqual(2, len(response.forms))
self.assertEqual(response.forms[0].id, 'person_search_header')
# even though there are only two forms on the page the list has
# two entries per form - one for the numeric identifier and one
# for the id
self.assertEqual(4, len(response.forms))
self.assertEqual(response.forms[1].id, 'person_search_header')

def test_any_constituency_page(self):
# Just a smoke test for the moment:
Expand Down
15 changes: 15 additions & 0 deletions candidates/tests/test_language_switcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django_webtest import WebTest


class TestLanguageSwitcher(WebTest):

def test_switch_language(self):
response = self.app.get('/')

response.mustcontain('Open data API')

form = response.forms['language_switcher']
form['language'] = 'cy-gb'
response = form.submit().follow()

response.mustcontain('Amdanom Ni')
23 changes: 23 additions & 0 deletions mysite/settings/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import re
import yaml

from django.conf import locale
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS, LANGUAGES
from django.utils.translation import ugettext_lazy as _
from django.utils.translation.trans_real import to_locale
Expand Down Expand Up @@ -59,6 +60,26 @@ def get_settings(conf_file_leafname, election_app=None, tests=False):
languages.append(('cy-gb', 'Welsh'))
languages.append(('es-cr', 'Costa Rican Spanish'))

# we need this to make the language switcher work because Django doesn't
# have any language information for these so if you try to tell it to
# switch to them it cannot and falls back to the existing/default language
EXTRA_LANG_INFO = {
'cy-gb': {
'bidi': False,
'code': 'cy-gb',
'name': 'Welsh',
'name_local': u'Cymraeg',
},
'es-cr': {
'bidi': False,
'code': 'es-cr',
'name': 'Spanish',
'name_local': u'español de Costa Rica',
},
}

locale.LANG_INFO.update(EXTRA_LANG_INFO)

# The language selection has been slightly complicated now that we
# have two es- languages: es-ar and es-cr. Chrome doesn't offer
# Costa Rican Spanish as one of its language choices, so the best
Expand Down Expand Up @@ -342,6 +363,7 @@ def get_settings(conf_file_leafname, election_app=None, tests=False):
},
'all': {
'source_filenames': (
'js/vendor/custom.modernizr.js',
'jquery/jquery-1.11.1.js',
'jquery/jquery-ui.js',
'foundation/js/foundation/foundation.js',
Expand All @@ -366,6 +388,7 @@ def get_settings(conf_file_leafname, election_app=None, tests=False):
'js/person_form.js',
'js/home_geolocation_form.js',
'js/versions.js',
'js/language-switcher.js',
),
'output_filename': 'js/all.js'
}
Expand Down
14 changes: 14 additions & 0 deletions mysite/templates/generic_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@
<div class="header__masthead">
<div class="container">
<a href="/" class="header__masthead__logo">{{ site.name }}</a>
<form id="language_switcher" action="{% url 'set_language' %}" method="post" class="nav-language js-language-switcher">
{% csrf_token %}
<select name="language" aria-label="Set site language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option lang="{{ language.code }}" value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.name_local }} ({{ language.code }})
Copy link
Contributor

@wfdd wfdd May 16, 2016

Choose a reason for hiding this comment

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

For semantic correctness, language.name_local should be marked up for lang, that is

<span lang="{{ language.code }}"> {{ language.name_local }}</span> ({{ language.code }})

Screen readers may also be able to use this information to pronounce the name in the 'local' language.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good spot!

</option>
{% endfor %}
</select>
<input type="submit" value="Set language">
</form>
<ul class="nav-links">
{% if user.is_authenticated %}
<li class="nav-links__item">{% blocktrans with username=user.username %}Signed in as <strong>{{ username }}</strong>{% endblocktrans %}</li>
Expand Down
1 change: 1 addition & 0 deletions mysite/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
url(r'^accounts/', include('allauth.urls')),
url(r'^upload_document/', include('official_documents.urls')),
url(r'^results/', include('results.urls')),
url(r'^i18n/', include('django.conf.urls.i18n')),
]

if settings.DEBUG:
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cffi==1.5.0
coverage==3.7.1
cryptography==1.2.2
decorator==4.0.4
Django==1.8.10
Django==1.8.13
django-allauth==0.21.0
django-appconf==1.0.1
django-braces==1.4.0
Expand Down