def firefox_all(request): ftl_files = 'firefox/all' product_android = firefox_android product_desktop = firefox_desktop # Human-readable product labels products = OrderedDict([ ('desktop_release', ftl('firefox-all-product-firefox', ftl_files=ftl_files)), ('desktop_beta', ftl('firefox-all-product-firefox-beta', ftl_files=ftl_files)), ('desktop_developer', ftl('firefox-all-product-firefox-developer', ftl_files=ftl_files)), ('desktop_nightly', ftl('firefox-all-product-firefox-nightly', ftl_files=ftl_files)), ('desktop_esr', ftl('firefox-all-product-firefox-esr', ftl_files=ftl_files)), ('android_release', ftl('firefox-all-product-firefox-android', ftl_files=ftl_files)), ('android_beta', ftl('firefox-all-product-firefox-android-beta', ftl_files=ftl_files)), ('android_nightly', ftl('firefox-all-product-firefox-android-nightly', ftl_files=ftl_files)), ]) channel_release = 'release' channel_beta = 'beta' channel_dev = 'devedition' channel_nightly = 'nightly' channel_esr = 'esr' channel_esr_next = 'esr_next' latest_release_version_desktop = product_desktop.latest_version( channel_release) latest_beta_version_desktop = product_desktop.latest_version(channel_beta) latest_developer_version_desktop = product_desktop.latest_version( channel_dev) latest_nightly_version_desktop = product_desktop.latest_version( channel_nightly) latest_esr_version_desktop = product_desktop.latest_version(channel_esr) latest_esr_next_version_desktop = product_desktop.latest_version( channel_esr_next) latest_release_version_android = product_android.latest_version( channel_release) latest_beta_version_android = product_android.latest_version(channel_beta) latest_nightly_version_android = product_android.latest_version( channel_nightly) context = { 'products': products.items(), 'desktop_release_platforms': product_desktop.platforms(channel_release), 'desktop_release_full_builds': product_desktop.get_filtered_full_builds( channel_release, latest_release_version_desktop), 'desktop_release_channel_label': product_desktop.channel_labels.get(channel_release, 'Firefox'), 'desktop_release_latest_version': latest_release_version_desktop, 'desktop_beta_platforms': product_desktop.platforms(channel_beta), 'desktop_beta_full_builds': product_desktop.get_filtered_full_builds(channel_beta, latest_beta_version_desktop), 'desktop_beta_channel_label': product_desktop.channel_labels.get(channel_beta, 'Firefox'), 'desktop_beta_latest_version': latest_beta_version_desktop, 'desktop_developer_platforms': product_desktop.platforms(channel_dev), 'desktop_developer_full_builds': product_desktop.get_filtered_full_builds( channel_dev, latest_developer_version_desktop), 'desktop_developer_channel_label': product_desktop.channel_labels.get(channel_dev, 'Firefox'), 'desktop_developer_latest_version': latest_developer_version_desktop, 'desktop_nightly_platforms': product_desktop.platforms(channel_nightly), 'desktop_nightly_full_builds': product_desktop.get_filtered_full_builds( channel_nightly, latest_nightly_version_desktop), 'desktop_nightly_channel_label': product_desktop.channel_labels.get(channel_nightly, 'Firefox'), 'desktop_nightly_latest_version': latest_nightly_version_desktop, 'desktop_esr_platforms': product_desktop.platforms(channel_esr), 'desktop_esr_full_builds': product_desktop.get_filtered_full_builds(channel_esr, latest_esr_version_desktop), 'desktop_esr_channel_label': product_desktop.channel_labels.get(channel_esr, 'Firefox'), 'desktop_esr_latest_version': latest_esr_version_desktop, 'android_release_platforms': product_android.platforms(channel_release), 'android_release_full_builds': product_android.get_filtered_full_builds( channel_release, latest_release_version_android), 'android_release_channel_label': product_android.channel_labels.get(channel_release, 'Firefox'), 'android_release_latest_version': latest_release_version_android, 'android_beta_platforms': product_android.platforms(channel_beta), 'android_beta_full_builds': product_android.get_filtered_full_builds(channel_beta, latest_beta_version_android), 'android_beta_channel_label': product_android.channel_labels.get(channel_beta, 'Firefox'), 'android_beta_latest_version': latest_beta_version_android, 'android_nightly_platforms': product_android.platforms(channel_nightly), 'android_nightly_full_builds': product_android.get_filtered_full_builds( channel_nightly, latest_nightly_version_android), 'android_nightly_channel_label': product_android.channel_labels.get(channel_nightly, 'Firefox'), 'android_nightly_latest_version': latest_nightly_version_android, } if latest_esr_next_version_desktop: context['desktop_esr_platforms_next'] = product_desktop.platforms( channel_esr_next, True) context[ 'desktop_esr_full_builds_next'] = product_desktop.get_filtered_full_builds( channel_esr_next, latest_esr_next_version_desktop) context['desktop_esr_channel_label_next'] = ( product_desktop.channel_labels.get(channel_esr_next, 'Firefox'), ) context['desktop_esr_next_version'] = latest_esr_next_version_desktop return l10n_utils.render(request, 'firefox/all-unified.html', context, ftl_files=ftl_files)
def test_ftl_view_util(self): assert fluent.ftl("fluent-title", locale="de", ftl_files="mozorg/fluent") == "Title in German"
class NewsletterFooterForm(forms.Form): """ Form used to subscribe to a single newsletter, typically in the footer of a page (see newsletters/middleware.py) but sometimes on a dedicated page. """ choice_labels = { "mozilla-foundation": ftl("multi-newsletter-form-checkboxes-label-mozilla"), "mozilla-and-you": ftl("multi-newsletter-form-checkboxes-label-firefox"), } email = forms.EmailField(widget=EmailInput(attrs={"required": "required"})) # first/last_name not yet included in email_newsletter_form helper # currently used on /contribute/friends/ (custom markup) first_name = forms.CharField(widget=forms.TextInput, required=False) last_name = forms.CharField(widget=forms.TextInput, required=False) fmt = forms.ChoiceField(widget=SimpleRadioSelect, choices=FORMATS, initial="H") privacy = forms.BooleanField(widget=PrivacyWidget) source_url = forms.CharField(required=False) newsletters = forms.MultipleChoiceField( widget=forms.CheckboxSelectMultiple()) # has to take a newsletters argument so it can figure # out which languages to list in the form. def __init__(self, newsletters, locale, data=None, *args, **kwargs): regions = product_details.get_regions(locale) regions = sorted(iter(regions.items()), key=itemgetter(1)) try: if isinstance(newsletters, str): newsletters = newsletters.split(",") newsletters = validate_newsletters(newsletters) except ValidationError: # replace with most common good newsletter # form validation will work with submitted data newsletters = ["mozilla-and-you"] lang = locale.lower() if "-" in lang: lang, country = lang.split("-", 1) else: country = "" regions.insert( 0, ("", ftl_lazy("newsletter-form-select-country-or-region", fallback="newsletter-form-select-country"))) lang_choices = get_lang_choices(newsletters) languages = [x[0] for x in lang_choices] if lang not in languages: # The lang from their locale is not one that our newsletters # are translated into. Initialize the language field to no # choice, to force the user to pick one of the languages that # we do support. lang = "" lang_choices.insert( 0, ("", ftl_lazy("newsletter-form-available-languages"))) super().__init__(data, *args, **kwargs) required_args = { "required": "required", "aria-required": "true", } country_widget = widgets.Select(attrs=required_args) country_label = ftl_lazy("newsletter-form-select-country-or-region", fallback="newsletter-form-select-country") self.fields["country"] = forms.ChoiceField(widget=country_widget, choices=regions, initial=country, required=False, label=country_label) lang_widget = widgets.Select(attrs=required_args) lang_label = ftl_lazy("newsletter-form-select-language", fallback="newsletter-form-available-languages") self.fields["lang"] = forms.TypedChoiceField(widget=lang_widget, choices=lang_choices, initial=lang, required=False, label=lang_label) self.fields["newsletters"].choices = [(n, self.choice_labels.get(n, n)) for n in newsletters] self.fields["newsletters"].initial = newsletters def clean_newsletters(self): return validate_newsletters(self.cleaned_data["newsletters"]) def clean_source_url(self): su = self.cleaned_data["source_url"].strip() if su: # limit to 255 characters by truncation return su[:255] return su
def __init__(self, attrs=None): choices = ( ("true", ftl("newsletter-form-yes")), ("false", ftl("newsletter-form-no")), ) super().__init__(attrs, choices)
def test_ftl_view_util_default_files(self): """Should use default FTL files""" assert fluent.ftl('fluent-title', locale='de') == 'Title in German'
def test_ftl_view_util_active_locale(self): """Should use activated locale if not provided""" translation.activate('fr') assert fluent.ftl('fluent-title') == 'Title in French'
def test_ftl_view_util_no_mutate_list(self): """Should not mutate the ftl_files list""" ftl_files = ['mozorg/fluent'] assert fluent.ftl('fluent-title', locale='de', ftl_files=ftl_files) == 'Title in German' assert ftl_files == ['mozorg/fluent']
def test_ftl_view_util_tuple(self): """Should be able to pass in a tuple of ftl files""" ftl_files = ('mozorg/fluent', ) assert fluent.ftl('fluent-title', locale='de', ftl_files=ftl_files) == 'Title in German'
def test_ftl_view_util(self): assert fluent.ftl('fluent-title', locale='de', ftl_files='mozorg/fluent') == 'Title in German'
def firefox_all(request): ftl_files = 'firefox/all' product_android = firefox_android product_desktop = firefox_desktop product_ios = firefox_ios # Human-readable product labels products = OrderedDict( [ ('desktop_release', ftl('firefox-all-product-firefox', ftl_files=ftl_files)), ('desktop_beta', ftl('firefox-all-product-firefox-beta', ftl_files=ftl_files)), ('desktop_developer', ftl('firefox-all-product-firefox-developer', ftl_files=ftl_files)), ('desktop_nightly', ftl('firefox-all-product-firefox-nightly', ftl_files=ftl_files)), ('desktop_esr', ftl('firefox-all-product-firefox-esr', ftl_files=ftl_files)), ('android_release', ftl('firefox-all-product-firefox-android', ftl_files=ftl_files)), ('android_beta', ftl('firefox-all-product-firefox-android-beta', ftl_files=ftl_files)), ('android_nightly', ftl('firefox-all-product-firefox-android-nightly', ftl_files=ftl_files)), ('ios_release', ftl('firefox-all-product-firefox-ios', ftl_files=ftl_files)), ] ) channel_release = 'release' channel_beta = 'beta' channel_dev = 'devedition' channel_nightly = 'nightly' channel_esr = 'esr' channel_esr_next = 'esr_next' latest_release_version_desktop = product_desktop.latest_version(channel_release) latest_beta_version_desktop = product_desktop.latest_version(channel_beta) latest_developer_version_desktop = product_desktop.latest_version(channel_dev) latest_nightly_version_desktop = product_desktop.latest_version(channel_nightly) latest_esr_version_desktop = product_desktop.latest_version(channel_esr) latest_esr_next_version_desktop = product_desktop.latest_version(channel_esr_next) latest_release_version_android = product_android.latest_version(channel_release) latest_beta_version_android = product_android.latest_version(channel_beta) latest_nightly_version_android = product_android.latest_version(channel_nightly) latest_release_version_ios = product_ios.latest_version(channel_release) lang_multi = ftl('firefox-all-lang-multi', ftl_files=ftl_files) context = { 'products': products.items(), 'desktop_release_platforms': product_desktop.platforms(channel_release), 'desktop_release_full_builds': product_desktop.get_filtered_full_builds( channel_release, latest_release_version_desktop ), 'desktop_release_channel_label': product_desktop.channel_labels.get( channel_release, 'Firefox' ), 'desktop_release_latest_version': latest_release_version_desktop, 'desktop_beta_platforms': product_desktop.platforms(channel_beta), 'desktop_beta_full_builds': product_desktop.get_filtered_full_builds( channel_beta, latest_beta_version_desktop ), 'desktop_beta_channel_label': product_desktop.channel_labels.get( channel_beta, 'Firefox' ), 'desktop_beta_latest_version': latest_beta_version_desktop, 'desktop_developer_platforms': product_desktop.platforms(channel_dev), 'desktop_developer_full_builds': product_desktop.get_filtered_full_builds( channel_dev, latest_developer_version_desktop ), 'desktop_developer_channel_label': product_desktop.channel_labels.get( channel_dev, 'Firefox' ), 'desktop_developer_latest_version': latest_developer_version_desktop, 'desktop_nightly_platforms': product_desktop.platforms(channel_nightly), 'desktop_nightly_full_builds': product_desktop.get_filtered_full_builds( channel_nightly, latest_nightly_version_desktop ), 'desktop_nightly_channel_label': product_desktop.channel_labels.get( channel_nightly, 'Firefox' ), 'desktop_nightly_latest_version': latest_nightly_version_desktop, 'desktop_esr_platforms': product_desktop.platforms(channel_esr), 'desktop_esr_full_builds': product_desktop.get_filtered_full_builds( channel_esr, latest_esr_version_desktop ), 'desktop_esr_channel_label': product_desktop.channel_labels.get( channel_esr, 'Firefox' ), 'desktop_esr_latest_version': latest_esr_version_desktop, 'android_release_platforms': [('android', 'Android')], 'android_release_full_builds': [{ 'locale': 'multi', 'name_en': lang_multi, 'name_native': lang_multi, 'platforms': {'android': {'download_url': settings.GOOGLE_PLAY_FIREFOX_LINK_UTMS}} }], 'android_release_channel_label': product_android.channel_labels.get( channel_release, 'Firefox' ), 'android_release_latest_version': latest_release_version_android, 'android_beta_platforms': [('android', 'Android')], 'android_beta_full_builds': [{ 'locale': 'multi', 'name_en': lang_multi, 'name_native': lang_multi, 'platforms': {'android': {'download_url': settings.GOOGLE_PLAY_FIREFOX_BETA_LINK}} }], 'android_beta_channel_label': product_android.channel_labels.get( channel_beta, 'Firefox' ), 'android_beta_latest_version': latest_beta_version_android, 'android_nightly_platforms': [('android', 'Android')], 'android_nightly_full_builds': [{ 'locale': 'multi', 'name_en': lang_multi, 'name_native': lang_multi, 'platforms': {'android': {'download_url': settings.GOOGLE_PLAY_FIREFOX_NIGHTLY_LINK}} }], 'android_nightly_channel_label': product_android.channel_labels.get( channel_nightly, 'Firefox' ), 'android_nightly_latest_version': latest_nightly_version_android, 'ios_release_platforms': [('ios', 'iOS')], 'ios_release_full_builds': [{ 'locale': 'multi', 'name_en': lang_multi, 'name_native': lang_multi, 'platforms': {'ios': {'download_url': settings.APPLE_APPSTORE_FIREFOX_LINK.replace('/{country}/', '/')}} }], 'ios_release_channel_label': product_ios.channel_labels.get( channel_release, 'Firefox' ), 'ios_release_latest_version': latest_release_version_ios, } if latest_esr_next_version_desktop: context['desktop_esr_platforms_next'] = product_desktop.platforms( channel_esr_next, True ) context[ 'desktop_esr_full_builds_next' ] = product_desktop.get_filtered_full_builds( channel_esr_next, latest_esr_next_version_desktop ) context['desktop_esr_channel_label_next'] = ( product_desktop.channel_labels.get(channel_esr_next, 'Firefox'), ) context['desktop_esr_next_version'] = latest_esr_next_version_desktop return l10n_utils.render(request, 'firefox/all-unified.html', context, ftl_files=ftl_files)
def newsletter_subscribe(request): if request.method == "POST": newsletters = request.POST.getlist("newsletters") form = NewsletterFooterForm(newsletters, l10n_utils.get_locale(request), request.POST) errors = [] if form.is_valid(): data = form.cleaned_data kwargs = {"format": data["fmt"]} # add optional data kwargs.update({ k: data[k] for k in [ "country", "lang", "source_url", "first_name", "last_name", ] if data[k] }) # NOTE this is not a typo; Referrer is misspelled in the HTTP spec # https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.36 if not kwargs.get("source_url") and request.headers.get("Referer"): kwargs["source_url"] = request.headers["Referer"] # Convert data["newsletters"] to a comma separated string. newsletters = data["newsletters"] if isinstance(newsletters, list): newsletters = ",".join(newsletters) try: basket.subscribe(data["email"], newsletters, **kwargs) except basket.BasketException as e: if e.code == basket.errors.BASKET_INVALID_EMAIL: errors.append(str(invalid_email_address)) else: log.exception( f"Error subscribing {data['email']} to newsletter(s) {newsletters}" ) errors.append(str(general_error)) else: if "email" in form.errors: errors.append(ftl("newsletter-form-please-enter-a-valid")) if "privacy" in form.errors: errors.append(ftl("newsletter-form-you-must-agree-to")) for fieldname in ("newsletters", "fmt", "lang", "country"): if fieldname in form.errors: errors.extend(form.errors[fieldname]) # form error messages may contain unsanitized user input errors = [escape(e) for e in errors] if request.headers.get("x-requested-with") == "XMLHttpRequest": # return JSON if errors: resp = { "success": False, "errors": errors, } else: resp = {"success": True} return JsonResponse(resp) else: ctx = {"newsletter_form": form} if not errors: ctx["success"] = True return l10n_utils.render(request, "newsletter/index.html", ctx, ftl_files=FTL_FILES) return l10n_utils.render(request, "newsletter/index.html", ftl_files=FTL_FILES)
def newsletter_subscribe(request): if request.method == 'POST': newsletters = request.POST.get('newsletters', None) form = NewsletterFooterForm(newsletters, l10n_utils.get_locale(request), request.POST) errors = [] if form.is_valid(): data = form.cleaned_data kwargs = {'format': data['fmt']} # add optional data kwargs.update( dict((k, data[k]) for k in [ 'country', 'lang', 'source_url', 'first_name', 'last_name', ] if data[k])) # NOTE this is not a typo; Referrer is misspelled in the HTTP spec # https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.36 if not kwargs.get('source_url') and request.META.get( 'HTTP_REFERER'): kwargs['source_url'] = request.META['HTTP_REFERER'] try: basket.subscribe(data['email'], data['newsletters'], **kwargs) except basket.BasketException as e: if e.code == basket.errors.BASKET_INVALID_EMAIL: errors.append(str(invalid_email_address)) else: log.exception("Error subscribing %s to newsletter %s" % (data['email'], data['newsletters'])) errors.append(str(general_error)) else: if 'email' in form.errors: errors.append(ftl('newsletter-form-please-enter-a-valid')) if 'privacy' in form.errors: errors.append(ftl('newsletter-form-you-must-agree-to')) for fieldname in ('fmt', 'lang', 'country'): if fieldname in form.errors: errors.extend(form.errors[fieldname]) # form error messages may contain unsanitized user input errors = list(map(escape, errors)) if request.is_ajax(): # return JSON if errors: resp = { 'success': False, 'errors': errors, } else: resp = {'success': True} return JsonResponse(resp) else: ctx = {'newsletter_form': form} if not errors: ctx['success'] = True return l10n_utils.render(request, 'newsletter/index.html', ctx, ftl_files=FTL_FILES) return l10n_utils.render(request, 'newsletter/index.html', ftl_files=FTL_FILES)
def firefox_all(request): ftl_files = "firefox/all" product_android = firefox_android product_desktop = firefox_desktop product_ios = firefox_ios # Human-readable product labels products = OrderedDict( [ ("desktop_release", ftl("firefox-all-product-firefox", ftl_files=ftl_files)), ("desktop_beta", ftl("firefox-all-product-firefox-beta", ftl_files=ftl_files)), ("desktop_developer", ftl("firefox-all-product-firefox-developer", ftl_files=ftl_files)), ("desktop_nightly", ftl("firefox-all-product-firefox-nightly", ftl_files=ftl_files)), ("desktop_esr", ftl("firefox-all-product-firefox-esr", ftl_files=ftl_files)), ("android_release", ftl("firefox-all-product-firefox-android", ftl_files=ftl_files)), ("android_beta", ftl("firefox-all-product-firefox-android-beta", ftl_files=ftl_files)), ("android_nightly", ftl("firefox-all-product-firefox-android-nightly", ftl_files=ftl_files)), ("ios_release", ftl("firefox-all-product-firefox-ios", ftl_files=ftl_files)), ] ) channel_release = "release" channel_beta = "beta" channel_dev = "devedition" channel_nightly = "nightly" channel_esr = "esr" channel_esr_next = "esr_next" latest_release_version_desktop = product_desktop.latest_version(channel_release) latest_beta_version_desktop = product_desktop.latest_version(channel_beta) latest_developer_version_desktop = product_desktop.latest_version(channel_dev) latest_nightly_version_desktop = product_desktop.latest_version(channel_nightly) latest_esr_version_desktop = product_desktop.latest_version(channel_esr) latest_esr_next_version_desktop = product_desktop.latest_version(channel_esr_next) latest_release_version_android = product_android.latest_version(channel_release) latest_beta_version_android = product_android.latest_version(channel_beta) latest_nightly_version_android = product_android.latest_version(channel_nightly) latest_release_version_ios = product_ios.latest_version(channel_release) lang_multi = ftl("firefox-all-lang-multi", ftl_files=ftl_files) context = { "products": products.items(), "desktop_release_platforms": product_desktop.platforms(channel_release), "desktop_release_full_builds": product_desktop.get_filtered_full_builds(channel_release, latest_release_version_desktop), "desktop_release_channel_label": product_desktop.channel_labels.get(channel_release, "Firefox"), "desktop_release_latest_version": latest_release_version_desktop, "desktop_beta_platforms": product_desktop.platforms(channel_beta), "desktop_beta_full_builds": product_desktop.get_filtered_full_builds(channel_beta, latest_beta_version_desktop), "desktop_beta_channel_label": product_desktop.channel_labels.get(channel_beta, "Firefox"), "desktop_beta_latest_version": latest_beta_version_desktop, "desktop_developer_platforms": product_desktop.platforms(channel_dev), "desktop_developer_full_builds": product_desktop.get_filtered_full_builds(channel_dev, latest_developer_version_desktop), "desktop_developer_channel_label": product_desktop.channel_labels.get(channel_dev, "Firefox"), "desktop_developer_latest_version": latest_developer_version_desktop, "desktop_nightly_platforms": product_desktop.platforms(channel_nightly), "desktop_nightly_full_builds": product_desktop.get_filtered_full_builds(channel_nightly, latest_nightly_version_desktop), "desktop_nightly_channel_label": product_desktop.channel_labels.get(channel_nightly, "Firefox"), "desktop_nightly_latest_version": latest_nightly_version_desktop, "desktop_esr_platforms": product_desktop.platforms(channel_esr), "desktop_esr_full_builds": product_desktop.get_filtered_full_builds(channel_esr, latest_esr_version_desktop), "desktop_esr_channel_label": product_desktop.channel_labels.get(channel_esr, "Firefox"), "desktop_esr_latest_version": latest_esr_version_desktop, "android_release_platforms": [("android", "Android")], "android_release_full_builds": [ { "locale": "multi", "name_en": lang_multi, "name_native": lang_multi, "platforms": {"android": {"download_url": settings.GOOGLE_PLAY_FIREFOX_LINK_UTMS}}, } ], "android_release_channel_label": product_android.channel_labels.get(channel_release, "Firefox"), "android_release_latest_version": latest_release_version_android, "android_beta_platforms": [("android", "Android")], "android_beta_full_builds": [ { "locale": "multi", "name_en": lang_multi, "name_native": lang_multi, "platforms": {"android": {"download_url": settings.GOOGLE_PLAY_FIREFOX_BETA_LINK}}, } ], "android_beta_channel_label": product_android.channel_labels.get(channel_beta, "Firefox"), "android_beta_latest_version": latest_beta_version_android, "android_nightly_platforms": [("android", "Android")], "android_nightly_full_builds": [ { "locale": "multi", "name_en": lang_multi, "name_native": lang_multi, "platforms": {"android": {"download_url": settings.GOOGLE_PLAY_FIREFOX_NIGHTLY_LINK}}, } ], "android_nightly_channel_label": product_android.channel_labels.get(channel_nightly, "Firefox"), "android_nightly_latest_version": latest_nightly_version_android, "ios_release_platforms": [("ios", "iOS")], "ios_release_full_builds": [ { "locale": "multi", "name_en": lang_multi, "name_native": lang_multi, "platforms": {"ios": {"download_url": settings.APPLE_APPSTORE_FIREFOX_LINK.replace("/{country}/", "/")}}, } ], "ios_release_channel_label": product_ios.channel_labels.get(channel_release, "Firefox"), "ios_release_latest_version": latest_release_version_ios, } if latest_esr_next_version_desktop: context["desktop_esr_platforms_next"] = product_desktop.platforms(channel_esr_next, True) context["desktop_esr_full_builds_next"] = product_desktop.get_filtered_full_builds(channel_esr_next, latest_esr_next_version_desktop) context["desktop_esr_channel_label_next"] = (product_desktop.channel_labels.get(channel_esr_next, "Firefox"),) context["desktop_esr_next_version"] = latest_esr_next_version_desktop return l10n_utils.render(request, "firefox/all-unified.html", context, ftl_files=ftl_files)