Skip to content

Commit

Permalink
Use existing form errors to flash error messages
Browse files Browse the repository at this point in the history
This is nice because we can reuse the translated strings of form error
messages in another context.

Suggested by Glandos.
  • Loading branch information
Baptiste Jonglez committed Jul 17, 2021
1 parent ed9aec9 commit ff2a669
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
21 changes: 21 additions & 0 deletions ihatemoney/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from flask import current_app, escape, redirect, render_template
from flask_babel import get_locale, lazy_gettext as _
import jinja2
from markupsafe import Markup
from werkzeug.routing import HTTPException, RoutingException


Expand Down Expand Up @@ -394,3 +395,23 @@ def render_localized_template(template_name_prefix, **context):
]
# render_template() supports a list of templates to try in order
return render_template(templates, **context)


def format_form_errors(form, prefix):
"""Format all form errors into a single string, with a string prefix in
front. Useful for flashing the result.
"""
if len(form.errors) == 0:
return ""
elif len(form.errors) == 1:
# I18N: Form error with only one error
return _("{prefix}: {error}").format(
prefix=prefix, error=form.errors.popitem()[1][0]
)
else:
error_list = "</li><li>".join(
str(error) for (field, errors) in form.errors.items() for error in errors
)
errors = f"<ul><li>{error_list}</li></ul>"
# I18N: Form error with a list of errors
return Markup(_("{prefix}:<br />{errors}").format(prefix=prefix, errors=errors))
16 changes: 8 additions & 8 deletions ihatemoney/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
from ihatemoney.utils import (
LoginThrottler,
Redirect303,
format_form_errors,
get_members,
list_of_dicts2csv,
list_of_dicts2json,
Expand Down Expand Up @@ -524,7 +525,7 @@ def delete_project():
return redirect(url_for(".home"))
else:
flash(
_("Error deleting project: wrong private code or wrong CSRF token"),
format_form_errors(form, _("Error deleting project")),
category="danger",
)
return redirect(request.headers.get("Referer") or url_for(".home"))
Expand Down Expand Up @@ -619,6 +620,7 @@ def invite():
@main.route("/<project_id>/")
def list_bills():
bill_form = get_billform_for(g.project)
# Used for CSRF validation
csrf_form = EmptyForm()
# set the last selected payer as default choice if exists
if "last_selected_payer" in session:
Expand Down Expand Up @@ -660,7 +662,7 @@ def reactivate(member_id):
# Used for CSRF validation
form = EmptyForm()
if not form.validate():
flash(_("CSRF Token: The CSRF token is invalid."), category="danger")
flash(format_form_errors(form, _("Error activating member")), category="danger")
return redirect(url_for(".list_bills"))

person = (
Expand All @@ -680,7 +682,7 @@ def remove_member(member_id):
# Used for CSRF validation
form = EmptyForm()
if not form.validate():
flash(_("CSRF Token: The CSRF token is invalid."), category="danger")
flash(format_form_errors(form, _("Error removing member")), category="danger")
return redirect(url_for(".list_bills"))

member = g.project.remove_member(member_id)
Expand Down Expand Up @@ -745,7 +747,7 @@ def delete_bill(bill_id):
# Used for CSRF validation
form = EmptyForm()
if not form.validate():
flash(_("CSRF Token: The CSRF token is invalid."), category="danger")
flash(format_form_errors(form, _("Error deleting bill")), category="danger")
return redirect(url_for(".list_bills"))

bill = Bill.query.get(g.project, bill_id)
Expand Down Expand Up @@ -822,7 +824,7 @@ def erase_history():
form = DestructiveActionProjectForm(id=g.project.id)
if not form.validate():
flash(
_("Error deleting project history: wrong private code or wrong CSRF token"),
format_form_errors(form, _("Error deleting project history")),
category="danger",
)
return redirect(url_for(".history"))
Expand All @@ -841,9 +843,7 @@ def strip_ip_addresses():
form = DestructiveActionProjectForm(id=g.project.id)
if not form.validate():
flash(
_(
"Error deleting recorded IP addresses: wrong private code or wrong CSRF token"
),
format_form_errors(form, _("Error deleting recorded IP addresses")),
category="danger",
)
return redirect(url_for(".history"))
Expand Down

0 comments on commit ff2a669

Please sign in to comment.