From 55150e5399f7d53b5c19744cab7fe737b4943a4e Mon Sep 17 00:00:00 2001 From: Quinten Steenhuis Date: Tue, 9 Jun 2026 10:53:54 -0400 Subject: [PATCH 1/2] Make interview intro prompt translatable instead of hardcoded string --- .gitignore | 2 ++ .../ALWeaver/data/templates/output.mako | 36 ++++++++++--------- .../ALWeaver/test_generate_from_path.py | 13 +++++++ 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 1d5c8e53..3f51c94c 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ package.json package-lock.json .mypy_cache/ dist/** +.codex +.creds diff --git a/docassemble/ALWeaver/data/templates/output.mako b/docassemble/ALWeaver/data/templates/output.mako index 1c1c824d..669703b7 100644 --- a/docassemble/ALWeaver/data/templates/output.mako +++ b/docassemble/ALWeaver/data/templates/output.mako @@ -1,7 +1,6 @@ <%doc> Initial metadata and includes ---- <% selected_includes = list( get_yml_deps_from_choices( @@ -43,6 +42,7 @@ jurisdiction_value = f"NAM-{country_value}" else: jurisdiction_value = "NAM-US" + intro_prompt_value = str(showifdef("interview.intro_prompt", "") or "") %> --- include: @@ -157,10 +157,11 @@ code: | --- code: | github_repo_name = 'docassemble-${ interview.package_title }' -% if defined('interview.intro_prompt'): +% if intro_prompt_value: --- -code: | - interview_short_title = "${ escape_quotes(interview.intro_prompt) }" +template: interview_short_title +content: | +${ indent(intro_prompt_value, by=2) } % endif % if generate_download_screen: --- @@ -304,12 +305,12 @@ subquestion: | <%text>${ al_recipient_bundle.as_pdf(key='preview') <%text>} % endif - Click the image to open it in a new tab. Click the "Edit answers" button - to edit your answers. + Open the form preview in a new tab. Use the "Edit answers" button to edit your + answers. - <%text>${ action_button_html(url_action('review_${ interview.interview_label }'), label='Edit answers', color='info') <%text>} + <%text>${ action_button_html(url_action('review_${ interview.interview_label }'), label=word('Edit answers'), color='info') <%text>} - Remember to come back to this window to continue and sign your form. + Return to this interview tab to continue and sign your form. continue button field: ${ interview.interview_label }_preview_question % endif <%doc> @@ -323,7 +324,7 @@ code: | % for custom_signature in interview.all_fields.custom_signatures(): --- question: | - ${custom_signature.variable.replace("_", " ").capitalize()}, sign below + ${custom_signature.variable.replace("_", " ").capitalize()}, add your signature signature: ${ custom_signature } % endfor % for field in interview.all_fields.skip_fields(): @@ -391,9 +392,10 @@ question: | subquestion: | Thank you <%text>${users}. Your form is ready to download and deliver. - View, download and send your form below. Click the "Edit answers" button to fix any mistakes. + Use the options on this page to view, download and send your form. Use the + "Edit answers" button to fix any mistakes. - <%text>${ action_button_html(url_action('review_${ interview.interview_label }'), label='Edit answers', color='info') <%text>} + <%text>${ action_button_html(url_action('review_${ interview.interview_label }'), label=word('Edit answers'), color='info') <%text>} <%text> ${ al_user_bundle.download_list_html() } @@ -446,7 +448,7 @@ code: | # ALDocument objects specify the metadata for each template objects: % if interview.include_next_steps: - - ${ interview.interview_label }_Post_interview_instructions: ALDocument.using(title="Instructions", filename="${ interview.interview_label }_next_steps.docx", enabled=True, has_addendum=False) + - ${ interview.interview_label }_Post_interview_instructions: ALDocument.using(title=word("Instructions"), filename="${ interview.interview_label }_next_steps.docx", enabled=True, has_addendum=False) % endif % if len(interview.uploaded_templates) == 1: - ${ interview.interview_label }_attachment: ALDocument.using(title="${ interview.title }", filename="${ interview.interview_label }", enabled=True, has_addendum=${ interview.all_fields.has_addendum_fields() }, ${ "default_overflow_message=AL_DEFAULT_OVERFLOW_MESSAGE" if interview.all_fields.has_addendum_fields() else ''}) @@ -459,20 +461,20 @@ objects: # Bundles group the ALDocuments into separate downloads, such as for court and for the user objects: % if interview.include_next_steps: - - al_user_bundle: ALDocumentBundle.using(elements=[${ f"{ interview.interview_label }_Post_interview_instructions"}, ${ interview.attachment_varnames()}], filename="${interview.interview_label}", title="All forms to download for your records", enabled=True) + - al_user_bundle: ALDocumentBundle.using(elements=[${ f"{ interview.interview_label }_Post_interview_instructions"}, ${ interview.attachment_varnames()}], filename="${interview.interview_label}", title=word("All forms to download for your records"), enabled=True) % else: - - al_user_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames()}], filename="${interview.interview_label}", title="All forms to download for your records", enabled=True) + - al_user_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames()}], filename="${interview.interview_label}", title=word("All forms to download for your records"), enabled=True) % endif % if interview.court_related: - - al_court_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames() }], filename="${interview.interview_label}", title="All forms to deliver to court", enabled=True) + - al_court_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames() }], filename="${interview.interview_label}", title=word("All forms to deliver to court"), enabled=True) % else: - - al_recipient_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames() }], filename="${interview.interview_label}", title="All forms to file", enabled=True) + - al_recipient_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames() }], filename="${interview.interview_label}", title=word("All forms to file"), enabled=True) % endif ---- # Each attachment defines a key in an ALDocument. We use `i` as the placeholder here so the same template is # used for "preview" and "final" keys, and logic in the template checks the value of # `i` to show or hide the user's signature % if interview.include_next_steps: +--- attachment: name: Post-interview-Instructions filename: ${ interview.interview_label }_next_steps diff --git a/docassemble/ALWeaver/test_generate_from_path.py b/docassemble/ALWeaver/test_generate_from_path.py index 875d52ff..46e068fe 100644 --- a/docassemble/ALWeaver/test_generate_from_path.py +++ b/docassemble/ALWeaver/test_generate_from_path.py @@ -124,6 +124,7 @@ def test_generate_from_docx(self): interview_overrides={ "state": "MA", "jurisdiction": "NAM-US-US+MA", + "intro_prompt": "A person's interview", }, field_definitions=[ { @@ -160,6 +161,18 @@ def test_generate_from_docx(self): ) self.assertRegex(yaml_text, r"(?m)^sections:\n(?:\s+- .+\n)+") self.assertRegex(yaml_text, r'(?m)^ nav\.set_section\("[-a-z_]+"\)$') + self.assertFalse(yaml_text.lstrip().startswith("---\n\n---")) + self.assertIn( + "template: interview_short_title\ncontent: |\n" + " A person's interview", + yaml_text, + ) + self.assertNotIn("interview_short_title =", yaml_text) + self.assertIn("label=word('Edit answers')", yaml_text) + self.assertIn( + 'title=word("All forms to download for your records")', + yaml_text, + ) self._run_dayamlchecker(result.yaml_path) def test_deterministic_package_contains_expected_files_including_next_steps(self): From 15a9e73b2fbd22bdb0a29e2fa9f4c49ae8da3241 Mon Sep 17 00:00:00 2001 From: Quinten Steenhuis Date: Tue, 9 Jun 2026 11:19:46 -0400 Subject: [PATCH 2/2] Use templates for .title so that's translatable too --- .../ALWeaver/data/templates/output.mako | 48 ++++++++++++++++--- .../ALWeaver/test_generate_from_path.py | 20 +++++++- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/docassemble/ALWeaver/data/templates/output.mako b/docassemble/ALWeaver/data/templates/output.mako index 669703b7..6590b4d0 100644 --- a/docassemble/ALWeaver/data/templates/output.mako +++ b/docassemble/ALWeaver/data/templates/output.mako @@ -448,28 +448,62 @@ code: | # ALDocument objects specify the metadata for each template objects: % if interview.include_next_steps: - - ${ interview.interview_label }_Post_interview_instructions: ALDocument.using(title=word("Instructions"), filename="${ interview.interview_label }_next_steps.docx", enabled=True, has_addendum=False) + - ${ interview.interview_label }_Post_interview_instructions: ALDocument.using(filename="${ interview.interview_label }_next_steps.docx", enabled=True, has_addendum=False) % endif % if len(interview.uploaded_templates) == 1: - - ${ interview.interview_label }_attachment: ALDocument.using(title="${ interview.title }", filename="${ interview.interview_label }", enabled=True, has_addendum=${ interview.all_fields.has_addendum_fields() }, ${ "default_overflow_message=AL_DEFAULT_OVERFLOW_MESSAGE" if interview.all_fields.has_addendum_fields() else ''}) + - ${ interview.interview_label }_attachment: ALDocument.using(filename="${ interview.interview_label }", enabled=True, has_addendum=${ interview.all_fields.has_addendum_fields() }, ${ "default_overflow_message=AL_DEFAULT_OVERFLOW_MESSAGE" if interview.all_fields.has_addendum_fields() else ''}) % else: % for document in interview.uploaded_templates: - - ${ varname(base_name(document.filename)) }: ALDocument.using(title="${ base_name(document.filename).capitalize().replace("_", " ") }", filename="${ base_name(document.filename) }", enabled=True, has_addendum=${ interview.all_fields.has_addendum_fields() }, ${ "default_overflow_message=AL_DEFAULT_OVERFLOW_MESSAGE" if interview.all_fields.has_addendum_fields() else ''}) + - ${ varname(base_name(document.filename)) }: ALDocument.using(filename="${ base_name(document.filename) }", enabled=True, has_addendum=${ interview.all_fields.has_addendum_fields() }, ${ "default_overflow_message=AL_DEFAULT_OVERFLOW_MESSAGE" if interview.all_fields.has_addendum_fields() else ''}) % endfor % endif --- # Bundles group the ALDocuments into separate downloads, such as for court and for the user objects: % if interview.include_next_steps: - - al_user_bundle: ALDocumentBundle.using(elements=[${ f"{ interview.interview_label }_Post_interview_instructions"}, ${ interview.attachment_varnames()}], filename="${interview.interview_label}", title=word("All forms to download for your records"), enabled=True) + - al_user_bundle: ALDocumentBundle.using(elements=[${ f"{ interview.interview_label }_Post_interview_instructions"}, ${ interview.attachment_varnames()}], filename="${interview.interview_label}", enabled=True) % else: - - al_user_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames()}], filename="${interview.interview_label}", title=word("All forms to download for your records"), enabled=True) + - al_user_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames()}], filename="${interview.interview_label}", enabled=True) % endif % if interview.court_related: - - al_court_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames() }], filename="${interview.interview_label}", title=word("All forms to deliver to court"), enabled=True) + - al_court_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames() }], filename="${interview.interview_label}", enabled=True) % else: - - al_recipient_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames() }], filename="${interview.interview_label}", title=word("All forms to file"), enabled=True) + - al_recipient_bundle: ALDocumentBundle.using(elements=[${ interview.attachment_varnames() }], filename="${interview.interview_label}", enabled=True) % endif +% if interview.include_next_steps: +--- +template: ${ interview.interview_label }_Post_interview_instructions.title +content: | + Instructions +% endif +% if len(interview.uploaded_templates) == 1: +--- +template: ${ interview.interview_label }_attachment.title +content: | +${ indent(str(interview.title), by=2) } +% else: +% for document in interview.uploaded_templates: +--- +template: ${ varname(base_name(document.filename)) }.title +content: | + ${ base_name(document.filename).capitalize().replace("_", " ") } +% endfor +% endif +--- +template: al_user_bundle.title +content: | + All forms to download for your records +% if interview.court_related: +--- +template: al_court_bundle.title +content: | + All forms to deliver to court +% else: +--- +template: al_recipient_bundle.title +content: | + All forms to file +% endif # Each attachment defines a key in an ALDocument. We use `i` as the placeholder here so the same template is # used for "preview" and "final" keys, and logic in the template checks the value of # `i` to show or hide the user's signature diff --git a/docassemble/ALWeaver/test_generate_from_path.py b/docassemble/ALWeaver/test_generate_from_path.py index 46e068fe..9f27e7be 100644 --- a/docassemble/ALWeaver/test_generate_from_path.py +++ b/docassemble/ALWeaver/test_generate_from_path.py @@ -170,9 +170,27 @@ def test_generate_from_docx(self): self.assertNotIn("interview_short_title =", yaml_text) self.assertIn("label=word('Edit answers')", yaml_text) self.assertIn( - 'title=word("All forms to download for your records")', + "template: test_docx_no_pdf_field_names_attachment.title\n" + "content: |\n" + " Test docx no pdf field names", yaml_text, ) + self.assertIn( + "template: al_user_bundle.title\n" + "content: |\n" + " All forms to download for your records", + yaml_text, + ) + self.assertIn( + "template: al_court_bundle.title\n" + "content: |\n" + " All forms to deliver to court", + yaml_text, + ) + self.assertNotRegex( + yaml_text, + r"ALDocument(?:Bundle)?\.using\([^\n]*\btitle=", + ) self._run_dayamlchecker(result.yaml_path) def test_deterministic_package_contains_expected_files_including_next_steps(self):