Skip to content
Draft
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
5 changes: 3 additions & 2 deletions hypha/addressfield/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _

from .widgets import AddressWidget

Expand Down Expand Up @@ -49,7 +50,7 @@ def clean(self, value, **kwargs):
try:
country_data = self.data[country]
except KeyError:
raise ValidationError("Invalid country selected") from None
raise ValidationError(_("Invalid country selected")) from None

fields = flatten_data(country_data["fields"])

Expand All @@ -59,7 +60,7 @@ def clean(self, value, **kwargs):
if missing_fields:
missing_field_name = [fields[field]["label"] for field in missing_fields]
raise ValidationError(
"Please provide data for: {}".format(", ".join(missing_field_name))
_("Please provide data for: {}").format(", ".join(missing_field_name))
)

return super().clean(value, **kwargs)
Expand Down
4 changes: 2 additions & 2 deletions hypha/apply/activity/adapters/activity_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,9 @@ def handle_report_frequency(self, config, **kwargs):

def handle_skipped_report(self, report, **kwargs):
if report.skipped:
return "Skipped a Report"
return _("Skipped a Report")
else:
return "Marked a Report as required"
return _("Marked a Report as required")

def handle_update_invoice_status(self, invoice, **kwargs):
base_message = _("Updated Invoice status to: {invoice_status}.")
Expand Down
9 changes: 6 additions & 3 deletions hypha/apply/activity/adapters/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.conf import settings
from django.contrib import messages
from django.utils.translation import gettext as _

from hypha.apply.activity.options import MESSAGES

Expand Down Expand Up @@ -192,11 +193,13 @@ def process_send(

if not settings.SEND_MESSAGES:
if recipient:
debug_message = "{} [to: {}]: {}".format(
self.adapter_type, recipient, message
debug_message = _("{adapter} [to: {recipient}]: {message}").format(
adapter=self.adapter_type, recipient=recipient, message=message
)
else:
debug_message = "{}: {}".format(self.adapter_type, message)
debug_message = _("{adapter}: {message}").format(
adapter=self.adapter_type, message=message
)
messages.add_message(request, messages.DEBUG, debug_message)

def create_logs(self, message, recipient, *events):
Expand Down
8 changes: 5 additions & 3 deletions hypha/apply/activity/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ class Meta:
"assign_to",
)
labels = {
"visibility": "Visible to",
"message": "Message",
"visibility": _("Visible to"),
"message": _("Message"),
}
help_texts = {
"visibility": "Select a relevant user role. Staff can view every comment."
"visibility": _(
"Select a relevant user role. Staff can view every comment."
)
}
widgets = {
"visibility": forms.RadioSelect(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Generated by Django 5.2.11 on 2026-03-03 14:58

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("activity", "0088_activity_deleted"),
]

operations = [
migrations.AlterModelOptions(
name="activity",
options={
"base_manager_name": "objects",
"ordering": ["-timestamp"],
"verbose_name": "activity",
"verbose_name_plural": "activities",
},
),
migrations.AlterModelOptions(
name="activityattachment",
options={
"verbose_name": "activity attachment",
"verbose_name_plural": "activity attachments",
},
),
migrations.AlterModelOptions(
name="event",
options={"verbose_name": "event", "verbose_name_plural": "events"},
),
migrations.AlterModelOptions(
name="message",
options={"verbose_name": "message", "verbose_name_plural": "messages"},
),
]
15 changes: 15 additions & 0 deletions hypha/apply/activity/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from django.utils import timezone
from django.utils.text import get_valid_filename
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy

from hypha.apply.utils.storage import PrivateStorage

Expand Down Expand Up @@ -183,6 +184,10 @@ class ActivityAttachment(models.Model):
upload_to=get_attachment_upload_path, storage=PrivateStorage()
)

class Meta:
verbose_name = gettext_lazy("activity attachment")
verbose_name_plural = gettext_lazy("activity attachments")

@property
def filename(self):
return os.path.basename(self.file.name)
Expand Down Expand Up @@ -240,6 +245,8 @@ class Activity(models.Model):
class Meta:
ordering = ["-timestamp"]
base_manager_name = "objects"
verbose_name = gettext_lazy("activity")
verbose_name_plural = gettext_lazy("activities")

def get_absolute_url(self):
# coverup for both submission and project as source.
Expand Down Expand Up @@ -381,6 +388,10 @@ class Event(models.Model):
object_id = models.PositiveIntegerField(blank=True, null=True)
source = GenericForeignKey("content_type", "object_id")

class Meta:
verbose_name = gettext_lazy("event")
verbose_name_plural = gettext_lazy("events")

def __str__(self):
if self.source and hasattr(self.source, "title"):
return f"{self.by} {self.get_type_display()} - {self.source.title}"
Expand Down Expand Up @@ -416,6 +427,10 @@ class Message(models.Model):
sent_in_email_digest = models.BooleanField(default=False)
objects = MessagesQueryset.as_manager()

class Meta:
verbose_name = gettext_lazy("message")
verbose_name_plural = gettext_lazy("messages")

def __str__(self):
return f"[{self.type}][{self.status}] {self.content}"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
hx-target="this"
hx-swap="outerHTML transition:true"
hx-select=".h-timeline"
>Show more...</a>
>{% trans "Show more..." %}</a>
{% endif %}
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
{% for role in activity.user.get_role_names %}
<span
class="inline-block py-0.5 px-2 text-sm font-semibold rounded-xl border border-gray-300 text-fg-muted"
data-tippy-content="This user is a {{ role }}"
data-tippy-content="{% blocktrans %}This user is a {{ role }}{% endblocktrans %}"
>
{{ role }}
</span>
Expand All @@ -34,7 +34,7 @@
{% endif %}

<a href="#communications--{{activity.id}}" class="hover:underline">
<span class="text-fg-muted">commented</span>
<span class="text-fg-muted">{% trans "commented" %}</span>
<relative-time
class="text-fg-muted"
datetime="{{ activity.timestamp|date:"c" }}"
Expand All @@ -58,7 +58,7 @@

{% with activity.visibility|visibility_display:request.user as visibility_text %}
<span class="flex gap-1 items-center py-0.5 px-1.5 text-xs uppercase rounded-xl border border-gray-300 text-fg-muted"
data-tippy-content="This is visible to {{ visibility_text }}">
data-tippy-content="{% blocktrans %}This is visible to {{ visibility_text }}{% endblocktrans %}">
{% heroicon_outline "eye" size=14 class="inline" aria_hidden=true %}
{{ visibility_text }}
</span>
Expand Down
9 changes: 5 additions & 4 deletions hypha/apply/activity/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, render
from django.utils.decorators import method_decorator
from django.utils.translation import gettext as _
from django.views.decorators.http import require_http_methods
from django.views.generic import ListView
from rolepermissions.checkers import has_object_permission
Expand Down Expand Up @@ -57,10 +58,10 @@ def edit_comment(request, pk):
activity = get_object_or_404(Activity, id=pk)

if activity.type != COMMENT or activity.user != request.user:
raise PermissionError("You can only edit your own comments")
raise PermissionDenied(_("You can only edit your own comments"))

if activity.deleted:
raise PermissionError("You can not edit a deleted comment")
raise PermissionDenied(_("You can not edit a deleted comment"))

if request.GET.get("action") == "cancel":
return render(
Expand Down Expand Up @@ -88,10 +89,10 @@ def delete_comment(request, pk):
activity = get_object_or_404(Activity, id=pk)

if activity.type != COMMENT or activity.user != request.user:
raise PermissionError("You can only delete your own comments")
raise PermissionDenied(_("You can only delete your own comments"))

if activity.deleted:
raise PermissionError("You can not delete a deleted comment")
raise PermissionDenied(_("You can not delete a deleted comment"))

if request.method == "DELETE":
activity = services.delete_comment(activity)
Expand Down
3 changes: 2 additions & 1 deletion hypha/apply/categories/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.urls import re_path
from django.utils.translation import gettext_lazy as _
from wagtail_modeladmin.options import ModelAdmin

from hypha.apply.utils.admin import AdminIcon
Expand All @@ -9,7 +10,7 @@


class CategoryAdmin(ModelAdmin):
menu_label = "Category Questions"
menu_label = _("Category Questions")
menu_icon = str(AdminIcon.CATEGORY)
model = Category

Expand Down
10 changes: 7 additions & 3 deletions hypha/apply/categories/admin_helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.contrib.admin.utils import quote
from django.utils.translation import gettext as _
from wagtail_modeladmin.helpers import ButtonHelper


Expand Down Expand Up @@ -33,9 +34,12 @@ def add_child_button(self, pk, child_verbose_name, **kwargs):
)
return {
"classname": classname,
"label": "Add %s %s" % (child_verbose_name, self.verbose_name),
"title": "Add %s %s under this one"
% (child_verbose_name, self.verbose_name),
"label": _("Add {child_verbose_name} {verbose_name}").format(
child_verbose_name=child_verbose_name, verbose_name=self.verbose_name
),
"title": _("Add {child_verbose_name} {verbose_name} under this one").format(
child_verbose_name=child_verbose_name, verbose_name=self.verbose_name
),
"url": self.url_helper.get_action_url("add_child", quote(pk)),
}

Expand Down
11 changes: 6 additions & 5 deletions hypha/apply/categories/admin_views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.contrib.admin.utils import unquote
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext as _
from wagtail_modeladmin.views import CreateView


Expand All @@ -18,11 +19,11 @@ def __init__(self, model_admin, parent_pk):

def get_page_title(self):
"""Generate a title that explains you are adding a child."""
title = super().get_page_title()
return title + " %s %s for %s" % (
self.model.node_child_verbose_name,
self.opts.verbose_name,
self.parent_instance,
return _("{title} {child_verbose_name} {verbose_name} for {parent}").format(
title=super().get_page_title(),
child_verbose_name=self.model.node_child_verbose_name,
verbose_name=self.opts.verbose_name,
parent=self.parent_instance,
)

def get_initial(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 5.2.11 on 2026-03-03 14:58

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("categories", "0007_rename_meta_terms_to_tags"),
]

operations = [
migrations.AlterModelOptions(
name="category",
options={"verbose_name": "Category", "verbose_name_plural": "Categories"},
),
migrations.AlterModelOptions(
name="option",
options={"verbose_name": "option", "verbose_name_plural": "options"},
),
]
22 changes: 15 additions & 7 deletions hypha/apply/categories/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.core.exceptions import PermissionDenied
from django.db import models
from django.template.loader import render_to_string
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
Expand All @@ -17,6 +18,10 @@ class Option(Orderable):
value = models.CharField(max_length=255)
category = ParentalKey("Category", related_name="options")

class Meta:
verbose_name = _("option")
verbose_name_plural = _("options")

def __str__(self):
return self.value

Expand Down Expand Up @@ -45,7 +50,8 @@ def __str__(self):
return self.name

class Meta:
verbose_name_plural = "Categories"
verbose_name = _("Category")
verbose_name_plural = _("Categories")


class MetaTerm(index.Indexed, MP_Node):
Expand Down Expand Up @@ -106,21 +112,21 @@ def get_as_listing_header(self):
)
return rendered

get_as_listing_header.short_description = "Name"
get_as_listing_header.short_description = _("Name")
get_as_listing_header.admin_order_field = "name"

def get_parent(self, *args, **kwargs):
return super().get_parent(*args, **kwargs)

get_parent.short_description = "Parent"
get_parent.short_description = _("Parent")

search_fields = [
index.SearchField("name"),
]

def delete(self):
if self.is_root():
raise PermissionDenied("Cannot delete root term.")
raise PermissionDenied(gettext("Cannot delete root term."))
else:
super().delete()

Expand Down Expand Up @@ -160,10 +166,12 @@ def __init__(self, *args, **kwargs):
if instance.is_root() or MetaTerm.objects.count() == 0:
self.fields["parent"].disabled = True
self.fields["parent"].required = False
self.fields["parent"].empty_label = "N/A - Root Term"
self.fields["parent"].empty_label = gettext("N/A - Root Term")
self.fields["parent"].widget = forms.HiddenInput()

self.fields["name"].label += " (Root - First term can be named root)"
self.fields["name"].label += gettext(
" (Root - First term can be named root)"
)
elif instance.id:
self.fields["parent"].initial = instance.get_parent()

Expand All @@ -172,7 +180,7 @@ def clean_parent(self):

if parent and parent.is_archived:
raise forms.ValidationError(
"The parent is archived therefore can not add child under it."
gettext("The parent is archived therefore can not add child under it.")
)

return parent
Expand Down
Loading
Loading