Add separate translations for each content type

Fixes #355
Fixes #538
This commit is contained in:
rubenwardy 2024-06-08 10:46:47 +01:00
parent a356a50abb
commit eb9466f346
9 changed files with 113 additions and 29 deletions

@ -111,7 +111,7 @@ def list_all():
selected_tags = set(qb.tags) selected_tags = set(qb.tags)
return render_template("packages/list.html", return render_template("packages/list.html",
query_hint=title, packages=query.items, pagination=query, query_hint=qb.query_hint, packages=query.items, pagination=query,
query=search, tags=tags, selected_tags=selected_tags, type=type_name, query=search, tags=tags, selected_tags=selected_tags, type=type_name,
authors=authors, packages_count=query.total, topics=topics, noindex=qb.noindex) authors=authors, packages_count=query.total, topics=topics, noindex=qb.noindex)

@ -162,10 +162,7 @@ def get_user_medals(user: User) -> Tuple[List[Medal], List[Medal]]:
if user_package_ranks: if user_package_ranks:
top_rank = user_package_ranks[2] top_rank = user_package_ranks[2]
top_type = PackageType.coerce(user_package_ranks[0]) top_type = PackageType.coerce(user_package_ranks[0])
if top_rank == 1: title = top_type.get_top_ordinal(top_rank)
title = gettext(u"Top %(type)s", type=top_type.text.lower())
else:
title = gettext(u"Top %(group)d %(type)s", group=top_rank, type=top_type.text.lower())
if top_type == PackageType.MOD: if top_type == PackageType.MOD:
icon = "fa-box" icon = "fa-box"
elif top_type == PackageType.GAME: elif top_type == PackageType.GAME:
@ -173,8 +170,7 @@ def get_user_medals(user: User) -> Tuple[List[Medal], List[Medal]]:
else: else:
icon = "fa-paint-brush" icon = "fa-paint-brush"
description = gettext(u"%(display_name)s has a %(type)s placed at #%(place)d.", description = top_type.get_top_ordinal_description(user.display_name, top_rank)
display_name=user.display_name, type=top_type.text.lower(), place=top_rank)
unlocked.append( unlocked.append(
Medal.make_unlocked(place_to_color(top_rank), icon, title, description)) Medal.make_unlocked(place_to_color(top_rank), icon, title, description))

@ -81,6 +81,33 @@ class PackageType(enum.Enum):
elif self == PackageType.TXP: elif self == PackageType.TXP:
return lazy_gettext("Texture Packs") return lazy_gettext("Texture Packs")
def get_top_ordinal(self, place: int):
if place == 1:
if self == PackageType.MOD:
return lazy_gettext("Top mod")
elif self == PackageType.GAME:
return lazy_gettext("Top game")
elif self == PackageType.TXP:
return lazy_gettext("Top texture pack")
else:
if self == PackageType.MOD:
return lazy_gettext("Top %(place)d mod", place=place)
elif self == PackageType.GAME:
return lazy_gettext("Top %(place)d game", place=place)
elif self == PackageType.TXP:
return lazy_gettext("Top %(place)d texture pack", place=place)
def get_top_ordinal_description(self, display_name: str, place: int):
if self == PackageType.MOD:
return lazy_gettext(u"%(display_name)s has a mod placed at #%(place)d.",
display_name=display_name, place=place)
elif self == PackageType.GAME:
return lazy_gettext(u"%(display_name)s has a game placed at #%(place)d.",
display_name=display_name, place=place)
elif self == PackageType.TXP:
return lazy_gettext(u"%(display_name)s has a texture pack placed at #%(place)d.",
display_name=display_name, place=place)
@classmethod @classmethod
def get(cls, name): def get(cls, name):
try: try:

@ -17,7 +17,7 @@
import datetime import datetime
import enum import enum
from flask import url_for from flask_babel import lazy_gettext
from flask_login import UserMixin from flask_login import UserMixin
from sqlalchemy import desc, text from sqlalchemy import desc, text
@ -400,36 +400,93 @@ class NotificationType(enum.Enum):
# Any other # Any other
OTHER = 0 OTHER = 0
@property
def get_title(self): def title(self):
return self.name.replace("_", " ").title() if self == NotificationType.PACKAGE_EDIT:
# NOTE: PACKAGE_EDIT notification type
return lazy_gettext("Package Edit")
elif self == NotificationType.PACKAGE_APPROVAL:
# NOTE: PACKAGE_APPROVAL notification type
return lazy_gettext("Package Approval")
elif self == NotificationType.NEW_THREAD:
# NOTE: NEW_THREAD notification type
return lazy_gettext("New Thread")
elif self == NotificationType.NEW_REVIEW:
# NOTE: NEW_REVIEW notification type
return lazy_gettext("New Review")
elif self == NotificationType.THREAD_REPLY:
# NOTE: THREAD_REPLY notification type
return lazy_gettext("Thread Reply")
elif self == NotificationType.BOT:
# NOTE: BOT notification type
return lazy_gettext("Bot")
elif self == NotificationType.MAINTAINER:
# NOTE: MAINTAINER notification type
return lazy_gettext("Maintainer")
elif self == NotificationType.EDITOR_ALERT:
# NOTE: EDITOR_ALERT notification type
return lazy_gettext("Editor Alert")
elif self == NotificationType.EDITOR_MISC:
# NOTE: EDITOR_MISC notification type
return lazy_gettext("Editor Misc")
elif self == NotificationType.OTHER:
# NOTE: OTHER notification type
return lazy_gettext("Other")
else:
raise "Unknown notification type"
def to_name(self): def to_name(self):
return self.name.lower() return self.name.lower()
def get_description(self): @property
def this_is(self):
if self == NotificationType.PACKAGE_EDIT: if self == NotificationType.PACKAGE_EDIT:
return "When another user edits your packages, releases, etc." return lazy_gettext("This is a Package Edit notification.")
elif self == NotificationType.PACKAGE_APPROVAL: elif self == NotificationType.PACKAGE_APPROVAL:
return "Notifications from editors related to the package approval process." return lazy_gettext("This is a Package Approval notification.")
elif self == NotificationType.NEW_THREAD: elif self == NotificationType.NEW_THREAD:
return "When a thread is created on your package." return lazy_gettext("This is a New Thread notification.")
elif self == NotificationType.NEW_REVIEW: elif self == NotificationType.NEW_REVIEW:
return "When a user posts a review on your package." return lazy_gettext("This is a New Review notification.")
elif self == NotificationType.THREAD_REPLY: elif self == NotificationType.THREAD_REPLY:
return "When someone replies to a thread you're watching." return lazy_gettext("This is a Thread Reply notification.")
elif self == NotificationType.BOT: elif self == NotificationType.BOT:
return "From a bot - for example, update notifications." return lazy_gettext("This is a Bot notification.")
elif self == NotificationType.MAINTAINER: elif self == NotificationType.MAINTAINER:
return "When your package's maintainers change." return lazy_gettext("This is a Maintainer change notification.")
elif self == NotificationType.EDITOR_ALERT: elif self == NotificationType.EDITOR_ALERT:
return "For editors: Important alerts." return lazy_gettext("This is an Editor Alert notification.")
elif self == NotificationType.EDITOR_MISC: elif self == NotificationType.EDITOR_MISC:
return "For editors: Minor notifications, including new threads." return lazy_gettext("This is an Editor Misc notification.")
elif self == NotificationType.OTHER: elif self == NotificationType.OTHER:
return "Minor notifications not important enough for a dedicated category." return lazy_gettext("This is an Other notification.")
else: else:
return "" raise "Unknown notification type"
@property
def description(self):
if self == NotificationType.PACKAGE_EDIT:
return lazy_gettext("When another user edits your packages, releases, etc.")
elif self == NotificationType.PACKAGE_APPROVAL:
return lazy_gettext("Notifications from editors related to the package approval process.")
elif self == NotificationType.NEW_THREAD:
return lazy_gettext("When a thread is created on your package.")
elif self == NotificationType.NEW_REVIEW:
return lazy_gettext("When a user posts a review on your package.")
elif self == NotificationType.THREAD_REPLY:
return lazy_gettext("When someone replies to a thread you're watching.")
elif self == NotificationType.BOT:
return lazy_gettext("From a bot - for example, update notifications.")
elif self == NotificationType.MAINTAINER:
return lazy_gettext("When your package's maintainers change.")
elif self == NotificationType.EDITOR_ALERT:
return lazy_gettext("For editors: Important alerts.")
elif self == NotificationType.EDITOR_MISC:
return lazy_gettext("For editors: Minor notifications, including new threads.")
elif self == NotificationType.OTHER:
return lazy_gettext("Minor notifications not important enough for a dedicated category.")
else:
raise "Unknown notification type"
def __str__(self): def __str__(self):
return self.name return self.name
@ -439,7 +496,7 @@ class NotificationType(enum.Enum):
@classmethod @classmethod
def choices(cls): def choices(cls):
return [(choice, choice.get_title()) for choice in cls] return [(choice, choice.title) for choice in cls]
@classmethod @classmethod
def coerce(cls, item): def coerce(cls, item):

@ -74,6 +74,10 @@ class QueryBuilder:
return ret return ret
@property
def query_hint(self):
return self.title
@property @property
def noindex(self): def noindex(self):
return (self.search is not None or len(self.tags) > 1 or len(self.types) > 1 or len(self.hide_flags) > 0 or return (self.search is not None or len(self.tags) > 1 or len(self.types) > 1 or len(self.hide_flags) > 0 or

@ -55,7 +55,7 @@
{% if type %}<input type="hidden" name="type" value="{{ type }}" />{% endif %} {% if type %}<input type="hidden" name="type" value="{{ type }}" />{% endif %}
<div class="input-group m-0"> <div class="input-group m-0">
<input class="form-control" name="q" type="text" <input class="form-control" name="q" type="text"
placeholder="{% if query_hint %}{{ _('Search %(type)s', type=query_hint | lower) }}{% else %}{{ _('Search all packages') }}{% endif %}" placeholder="{% if query_hint %}{{ _('Search %(type)s', type=query_hint) }}{% else %}{{ _('Search all packages') }}{% endif %}"
value="{{ query or ''}}"> value="{{ query or ''}}">
<button type="submit" class="btn btn-secondary" title="{{ _('Search') }}"> <button type="submit" class="btn btn-secondary" title="{{ _('Search') }}">
<i class="fas fa-search"></i> <i class="fas fa-search"></i>

@ -34,5 +34,5 @@
{{ _("Unsubscribe") }} {{ _("Unsubscribe") }}
</a> <br> </a> <br>
{{ _("This is a '%(type)s' notification.", type=notification.type.get_title()) }} {{ notification.type.this_is }}
{% endblock %} {% endblock %}

@ -46,7 +46,7 @@
<div class="alert alert-secondary"> <div class="alert alert-secondary">
<a class="float-end btn btn-sm btn-default" href="/help/package_config/#cdbjson" target="_blank">{{ _("Read more") }}</a> <a class="float-end btn btn-sm btn-default" href="/help/package_config/#cdbjson" target="_blank">{{ _("Read more") }}</a>
{{ _("You can include a .cdb.json file in your %(type)s to update these details automatically.", type=package.type.text.lower()) }} {{ _("You can include a .cdb.json file in your package to update these details automatically.") }}
</div> </div>
{% endif %} {% endif %}

@ -52,8 +52,8 @@
</tr> </tr>
{% for type in types %} {% for type in types %}
<tr> <tr>
<td>{{ type.get_title() }}</td> <td>{{ type.title }}</td>
<td>{{ type.get_description() }}</td> <td>{{ type.description }}</td>
<td style="text-align: center;"> <td style="text-align: center;">
{{ render_checkbox_field(form["pref_" + type.to_name()]) }} {{ render_checkbox_field(form["pref_" + type.to_name()]) }}
</td> </td>