Display different date formats based on locale

This commit is contained in:
Tasos Katsoulas 2024-09-13 13:44:54 +03:00
Родитель 55a4ef72a9
Коммит ef0db4c727
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 66D7743B4FCCFCBC
7 изменённых файлов: 44 добавлений и 36 удалений

Просмотреть файл

@ -2,7 +2,7 @@
{% from 'products/includes/topic_macros.html' import topic_sidebar, topic_tabs %}
{% from 'products/includes/product_macros.html' import product_dropdown %}
{% from 'includes/common_macros.html' import download_firefox, sumo_banner %}
{% from 'wiki/includes/document_macros.html' import document_metadata %}
{% from 'wiki/includes/document_macros.html' import document_metadata with context %}
{% from "questions/includes/aaq_macros.html" import aaq_widget %}
{% if product %}
@ -72,7 +72,7 @@
</a>
</h2>
<p>{{ document['document_summary'] }}</p>
{{ document_metadata(document['created'], document['is_past_thirty_days'], document['is_first_revision'], document['product_titles'], helpful_votes=None, metadata_type="list") }}
{{ document_metadata(document['created'], document['is_first_revision'], document['product_titles'], helpful_votes=None, metadata_type="list") }}
</div>
</article>
{% endfor %}

Просмотреть файл

@ -1,5 +1,4 @@
import json
from datetime import datetime, timedelta
from django.conf import settings
from django.db.models import Exists, OuterRef, Q
@ -152,9 +151,7 @@ def document_listing(request, topic_slug, product_slug=None, subtopic_slug=None)
documents, fallback_documents = documents_for(request.user, **doc_kw)
thirty_days_ago = datetime.now() - timedelta(days=30)
for document in documents:
document["is_past_thirty_days"] = document["created"] < thirty_days_ago
document["is_first_revision"] = (
Revision.objects.filter(document=document["id"], is_approved=True).count() == 1
)

Просмотреть файл

@ -642,7 +642,7 @@ INSTALLED_APPS: tuple[str, ...] = (
"django.contrib.sites",
"django.contrib.messages",
"django.contrib.staticfiles",
"django_jinja.contrib._humanize",
"django_jinja",
"graphene_django",
"mozilla_django_oidc",
"corsheaders",

Просмотреть файл

@ -8,16 +8,17 @@ from zoneinfo import ZoneInfo
import bleach
import jinja2
import wikimarkup.parser
from babel import localedata
from babel.dates import format_date, format_datetime, format_time
from babel.numbers import format_decimal
from django.conf import settings
from django.contrib.humanize.templatetags.humanize import naturaltime
from django.http import QueryDict
from django.template.loader import render_to_string
from django.templatetags.static import static as django_static
from django.utils.encoding import smart_bytes, smart_str
from django.utils.http import urlencode
from django.utils.timezone import get_default_timezone, is_aware, is_naive
from django.utils.timezone import now as django_now
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy as _lazy
from django.utils.translation import ngettext
@ -231,15 +232,12 @@ def _babel_locale(locale):
def _contextual_locale(context):
"""Return locale from the context, falling back to a default if invalid."""
request = context.get("request")
locale = request.LANGUAGE_CODE
if not localedata.exists(locale):
locale = settings.LANGUAGE_CODE
return locale
return request.LANGUAGE_CODE if request else settings.LANGUAGE_CODE
@jinja2.pass_context
@library.global_function
def datetimeformat(context, value, format="shortdatetime"):
def datetimeformat(context, value, format="shortdatetime", use_naturaltime=False):
"""
Returns a formatted date/time using Babel's locale settings. Uses the
timezone from settings.py, if the user has not been authenticated.
@ -274,18 +272,21 @@ def datetimeformat(context, value, format="shortdatetime"):
convert_value = new_value.astimezone(convert_tzinfo)
locale = _babel_locale(_contextual_locale(context))
# If within a day, 24 * 60 * 60 = 86400s
if format == "shortdatetime":
if use_naturaltime and (django_now().astimezone(convert_tzinfo) - convert_value).days < 30:
return naturaltime(convert_value)
if format == "shortdatetime" or format == "shortdate":
# Check if the date is today
today = datetime.datetime.now(tz=convert_tzinfo).toordinal()
kwargs = {"format": "short", "tzinfo": convert_tzinfo, "locale": locale}
if convert_value.toordinal() == today:
formatted = _lazy("Today at %s") % format_time(
convert_value, format="short", tzinfo=convert_tzinfo, locale=locale
)
formatted = _lazy("Today at %s") % format_time(convert_value, **kwargs)
else:
formatted = format_datetime(
convert_value, format="short", tzinfo=convert_tzinfo, locale=locale
)
if format == "shortdatetime":
formatted = format_datetime(convert_value, **kwargs)
else:
del kwargs["tzinfo"]
formatted = format_date(convert_value, **kwargs)
elif format == "longdatetime":
formatted = format_datetime(
convert_value, format="long", tzinfo=convert_tzinfo, locale=locale

Просмотреть файл

@ -1,7 +1,14 @@
{% extends "wiki/base.html" %}
{% from "wiki/includes/sidebar_modules.html" import document_tools, document_notifications, related_products_sidebar with context %}
{% from "wiki/includes/document_macros.html" import contributor_list, document_title, document_messages, document_metadata, document_content, inpage_contact_cta, topic_list, related_documents %}
{% from "wiki/includes/document_macros.html" import contributor_list,
document_title,
document_messages,
document_content,
inpage_contact_cta,
topic_list,
related_documents,
document_metadata with context %}
{% from "wiki/includes/document_macros.html" import vote_form with context %}
{% from "includes/common_macros.html" import download_firefox, sumo_banner %}
{% from "questions/includes/aaq_macros.html" import aaq_widget %}
@ -87,7 +94,7 @@
<article class="wiki-doc">
{{ document_messages(document, redirected_from) }}
{% if not document.is_archived %}
{{ document_metadata(document.current_revision.created, is_past_thirty_days, is_first_revision, product_titles, helpful_votes, metadata_type="document") }}
{{ document_metadata(document.current_revision.created, is_first_revision, product_titles, helpful_votes, metadata_type="document") }}
{% endif %}
{{ document_content(document, fallback_reason, request, settings, document_css_class, any_localizable_revision, full_locale_name) }}

Просмотреть файл

@ -12,7 +12,7 @@
<h1 class="sumo-page-heading">{{ document.title }}</h1>
{%- endmacro %}
{% macro document_metadata(created_date, is_past_thirty_days, is_first_revision, product_titles, helpful_votes, metadata_type) -%}
{% macro document_metadata(created_date, is_first_revision, product_titles, helpful_votes, metadata_type) -%}
{% set truncate_length = 25 if helpful_votes else 50 %}
<div id="document_metadata" class="{% if metadata_type=="list" %}has-border-top{% else %}has-border-bottom{% endif %}">
<span class="product tooltip-container">
@ -20,14 +20,18 @@
<span class="tooltip">{{ product_titles }}</span>
</span>
{% if created_date %}
<span class="last-updated">
<img class="pencil" src="{{ webpack_static('sumo/img/pencil.svg') }}" /> <strong>{% if is_first_revision %}{{ _("Created") }}{% else %}{{ _("Last updated") }}{% endif %}:</strong> <span class="time">{% if is_past_thirty_days %}{{ created_date.strftime('%m/%d/%Y') }}{% else %}{{ created_date|naturaltime }}{% endif %}</span>
</span>
<span class="last-updated">
<img class="pencil" src="{{ webpack_static('sumo/img/pencil.svg') }}" />
<strong>{% if is_first_revision %}{{ _("Created") }}{% else %}{{ _("Last updated") }}{% endif %}:</strong>
<span class="time">
{{ datetimeformat(created_date, format="shortdate", use_naturaltime=True) }}
</span>
</span>
{% endif %}
{% if helpful_votes %}
<span class="helpful-info">
<img class="thumbsup" src="{{ webpack_static('sumo/img/thumbs-up.svg') }}"/>{# L10n: {0} is 'helpful-count', {1} is the actual percentage and {2} is the percent sign. #}{{ _('<span class="{0}">{1}{2}</span> of users voted this helpful')|fe("helpful-count", helpful_votes, "%") }}
</span>
<span class="helpful-info">
<img class="thumbsup" src="{{ webpack_static('sumo/img/thumbs-up.svg') }}"/>{# L10n: {0} is 'helpful-count', {1} is the actual percentage and {2} is the percent sign. #}{{ _('<span class="{0}">{1}{2}</span> of users voted this helpful')|fe("helpful-count", helpful_votes, "%") }}
</span>
{% endif %}
</div>
{%- endmacro %}

Просмотреть файл

@ -3,7 +3,6 @@ import logging
import time
from datetime import datetime
from datetime import time as datetime_time
from datetime import timedelta
from functools import wraps
from django.conf import settings
@ -15,7 +14,12 @@ from django.core.exceptions import PermissionDenied
from django.db.models import Count, Exists, OuterRef, Q
from django.db.models.functions import Now, TruncDate
from django.forms.utils import ErrorList
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect
from django.http import (
Http404,
HttpResponse,
HttpResponseBadRequest,
HttpResponseRedirect,
)
from django.shortcuts import get_object_or_404, redirect, render
from django.template.loader import render_to_string
from django.utils.cache import patch_vary_headers
@ -294,15 +298,10 @@ def document(request, document_slug, document=None):
else 0
)
is_past_thirty_days = False
if doc.current_revision:
is_past_thirty_days = doc.current_revision.created < (datetime.now() - timedelta(days=30))
is_first_revision = doc.revisions.filter(is_approved=True).count() == 1
data = {
"document": doc,
"is_past_thirty_days": is_past_thirty_days,
"is_first_revision": is_first_revision,
"redirected_from": redirected_from,
"contributors": contributors,