From 0e3f68622f11d1db21f2224d93adfa7acde6669a Mon Sep 17 00:00:00 2001
From: Seamus Johnston
Date: Thu, 2 Feb 2023 14:30:00 -0600
Subject: [PATCH] Bypass Django internal form rendering
The purpose of this change is to allow direct use of Django templates
to make edits to how form fields and labels are rendered, while
retaining the validation logic provided by Django's extensive field and
widget library.
This commit additional contains:
- Remove `REQUIRED_SUFFIX`, as it is handled by the templates now
- Remove `required=True` from form fields, as this is the default
- Remove `required=False` from fields where it was added as workaround
for conditionally required questions which Django form wizard
couldn't handle
- Replace `clean_is_policy_acknowledged` with `error_messages` dict
- Remove duplicate nil entry for Federal Agency dropdown
- Update `DOMAIN_REGEX` to match whole string
- Subtle changes to `is_valid` and `get_forms` in ApplicationWizard to
reduce database calls and use form object's initial data correctly
---
src/registrar/forms/application_wizard.py | 77 +-----
src/registrar/models/domain.py | 2 +-
src/registrar/models/domain_application.py | 1 -
.../templates/application_anything_else.html | 31 +--
.../application_authorizing_official.html | 38 ++-
.../templates/application_current_sites.html | 47 ++--
.../templates/application_dotgov_domain.html | 93 ++++---
src/registrar/templates/application_form.html | 65 +++--
.../templates/application_org_contact.html | 42 ++--
.../templates/application_org_election.html | 33 +--
.../templates/application_org_federal.html | 33 +--
.../templates/application_org_type.html | 36 +--
.../templates/application_other_contacts.html | 47 ++--
.../templates/application_purpose.html | 54 ++--
.../templates/application_requirements.html | 234 ++++++++++--------
.../templates/application_review.html | 13 +-
.../templates/application_security_email.html | 39 +--
.../application_tribal_government.html | 37 +--
.../templates/application_type_of_work.html | 63 +----
.../templates/application_your_contact.html | 36 ++-
.../templates/django/forms/label.html | 9 +
.../templates/django/forms/widgets/attrs.html | 3 +
.../django/forms/widgets/checkbox.html | 3 +
.../templates/django/forms/widgets/email.html | 3 +
.../django/forms/widgets/hidden.html | 1 +
.../templates/django/forms/widgets/input.html | 8 +
.../django/forms/widgets/multiple_input.html | 20 ++
.../django/forms/widgets/number.html | 3 +
.../django/forms/widgets/password.html | 3 +
.../templates/django/forms/widgets/radio.html | 3 +
.../django/forms/widgets/radio_option.html | 1 +
.../forms/widgets/regionalphonenumber.html | 3 +
.../django/forms/widgets/select.html | 14 ++
.../django/forms/widgets/select_option.html | 1 +
.../templates/django/forms/widgets/text.html | 3 +
.../django/forms/widgets/textarea.html | 5 +
.../templates/django/forms/widgets/url.html | 3 +
.../templates/includes/input_with_errors.html | 95 ++++---
.../templates/includes/radio_button.html | 14 --
src/registrar/templatetags/field_helpers.py | 155 +++++++++---
src/registrar/views/application.py | 19 +-
src/registrar/views/utility/steps_helper.py | 2 +-
42 files changed, 740 insertions(+), 652 deletions(-)
create mode 100644 src/registrar/templates/django/forms/label.html
create mode 100644 src/registrar/templates/django/forms/widgets/attrs.html
create mode 100644 src/registrar/templates/django/forms/widgets/checkbox.html
create mode 100644 src/registrar/templates/django/forms/widgets/email.html
create mode 100644 src/registrar/templates/django/forms/widgets/hidden.html
create mode 100644 src/registrar/templates/django/forms/widgets/input.html
create mode 100644 src/registrar/templates/django/forms/widgets/multiple_input.html
create mode 100644 src/registrar/templates/django/forms/widgets/number.html
create mode 100644 src/registrar/templates/django/forms/widgets/password.html
create mode 100644 src/registrar/templates/django/forms/widgets/radio.html
create mode 100644 src/registrar/templates/django/forms/widgets/radio_option.html
create mode 100644 src/registrar/templates/django/forms/widgets/regionalphonenumber.html
create mode 100644 src/registrar/templates/django/forms/widgets/select.html
create mode 100644 src/registrar/templates/django/forms/widgets/select_option.html
create mode 100644 src/registrar/templates/django/forms/widgets/text.html
create mode 100644 src/registrar/templates/django/forms/widgets/textarea.html
create mode 100644 src/registrar/templates/django/forms/widgets/url.html
delete mode 100644 src/registrar/templates/includes/radio_button.html
diff --git a/src/registrar/forms/application_wizard.py b/src/registrar/forms/application_wizard.py
index 6f08a692b..cec6a777f 100644
--- a/src/registrar/forms/application_wizard.py
+++ b/src/registrar/forms/application_wizard.py
@@ -6,20 +6,12 @@ from phonenumber_field.formfields import PhoneNumberField # type: ignore
from django import forms
from django.core.validators import RegexValidator
-from django.utils.safestring import mark_safe
from registrar.models import Contact, DomainApplication, Domain
from registrar.utility import errors
logger = logging.getLogger(__name__)
-# no sec because this use of mark_safe does not introduce a cross-site scripting
-# vulnerability because there is no untrusted content inside. It is
-# only being used to pass a specific HTML entity into a template.
-REQUIRED_SUFFIX = mark_safe( # nosec
- ' *'
-)
-
class RegistrarForm(forms.Form):
"""
@@ -70,6 +62,13 @@ class RegistrarFormSet(forms.BaseFormSet):
# save a reference to an application object
self.application = kwargs.pop("application", None)
super(RegistrarFormSet, self).__init__(*args, **kwargs)
+ # quick workaround to ensure that the HTML `required`
+ # attribute shows up on required fields for any forms
+ # in the formset which have data already (stated another
+ # way: you can leave a form in the formset blank, but
+ # if you opt to fill it out, you must fill it out _right_)
+ for index in range(self.initial_form_count()):
+ self.forms[index].use_required_attribute = True
def should_delete(self, cleaned):
"""Should this entry be deleted from the database?"""
@@ -150,7 +149,6 @@ class RegistrarFormSet(forms.BaseFormSet):
class OrganizationTypeForm(RegistrarForm):
organization_type = forms.ChoiceField(
- required=True,
choices=DomainApplication.OrganizationChoices.choices,
widget=forms.RadioSelect,
error_messages={"required": "Select the type of organization you represent."},
@@ -170,7 +168,6 @@ class TribalGovernmentForm(RegistrarForm):
tribe_name = forms.CharField(
label="Enter the tribe that you represent",
- label_suffix=REQUIRED_SUFFIX,
error_messages={"required": "Enter the tribe you represent."},
)
@@ -208,8 +205,7 @@ class OrganizationElectionForm(RegistrarForm):
(True, "Yes"),
(False, "No"),
],
- ),
- required=False, # use field validation to require an answer
+ )
)
def clean_is_election_board(self):
@@ -234,18 +230,13 @@ class OrganizationContactForm(RegistrarForm):
# if it has been filled in when required.
required=False,
choices=[("", "--Select--")] + DomainApplication.AGENCY_CHOICES,
- label_suffix=REQUIRED_SUFFIX,
)
organization_name = forms.CharField(
label="Organization name",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={"required": "Enter the name of your organization."},
)
address_line1 = forms.CharField(
label="Street address",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={"required": "Enter the street address of your organization."},
)
address_line2 = forms.CharField(
@@ -254,8 +245,6 @@ class OrganizationContactForm(RegistrarForm):
)
city = forms.CharField(
label="City",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": "Enter the city where your organization is located."
},
@@ -263,8 +252,6 @@ class OrganizationContactForm(RegistrarForm):
state_territory = forms.ChoiceField(
label="State, territory, or military post",
choices=[("", "--Select--")] + DomainApplication.StateTerritoryChoices.choices,
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": (
"Select the state, territory, or military post where your organization"
@@ -274,7 +261,6 @@ class OrganizationContactForm(RegistrarForm):
)
zipcode = forms.CharField(
label="Zip code",
- label_suffix=REQUIRED_SUFFIX,
validators=[
RegexValidator(
"^[0-9]{5}(?:-[0-9]{4})?$|^$",
@@ -313,7 +299,6 @@ class TypeOfWorkForm(RegistrarForm):
type_of_work = forms.CharField(
# label has to end in a space to get the label_suffix to show
label="What type of work does your organization do? ",
- label_suffix=REQUIRED_SUFFIX,
widget=forms.Textarea(),
error_messages={"required": "Enter the type of work your organization does."},
)
@@ -326,7 +311,6 @@ class TypeOfWorkForm(RegistrarForm):
" legislation, applicable bylaws or charter, or other documentation to"
" support your claims. "
),
- label_suffix=REQUIRED_SUFFIX,
widget=forms.Textarea(),
error_messages={
"required": (
@@ -356,8 +340,6 @@ class AuthorizingOfficialForm(RegistrarForm):
first_name = forms.CharField(
label="First name / given name",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": (
"Enter the first name / given name of your authorizing official."
@@ -370,8 +352,6 @@ class AuthorizingOfficialForm(RegistrarForm):
)
last_name = forms.CharField(
label="Last name / family name",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": (
"Enter the last name / family name of your authorizing official."
@@ -380,8 +360,6 @@ class AuthorizingOfficialForm(RegistrarForm):
)
title = forms.CharField(
label="Title or role in your organization",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": (
"Enter the title or role your authorizing official has in your"
@@ -391,7 +369,6 @@ class AuthorizingOfficialForm(RegistrarForm):
)
email = forms.EmailField(
label="Email",
- label_suffix=REQUIRED_SUFFIX,
error_messages={
"invalid": (
"Enter an email address in the required format, like name@example.com."
@@ -400,8 +377,6 @@ class AuthorizingOfficialForm(RegistrarForm):
)
phone = PhoneNumberField(
label="Phone",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": "Enter the phone number for your authorizing official."
},
@@ -600,8 +575,6 @@ class YourContactForm(RegistrarForm):
first_name = forms.CharField(
label="First name / given name",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={"required": "Enter your first name / given name."},
)
middle_name = forms.CharField(
@@ -610,14 +583,10 @@ class YourContactForm(RegistrarForm):
)
last_name = forms.CharField(
label="Last name / family name",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={"required": "Enter your last name / family name."},
)
title = forms.CharField(
label="Title or role in your organization",
- required=True,
- label_suffix=REQUIRED_SUFFIX,
error_messages={
"required": (
"Enter your title or role in your organization (e.g., Chief Information"
@@ -627,8 +596,6 @@ class YourContactForm(RegistrarForm):
)
email = forms.EmailField(
label="Email",
- required=True,
- label_suffix=REQUIRED_SUFFIX,
error_messages={
"invalid": (
"Enter your email address in the required format, like"
@@ -638,8 +605,6 @@ class YourContactForm(RegistrarForm):
)
phone = PhoneNumberField(
label="Phone",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={"required": "Enter your phone number."},
)
@@ -647,8 +612,6 @@ class YourContactForm(RegistrarForm):
class OtherContactsForm(RegistrarForm):
first_name = forms.CharField(
label="First name / given name",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": "Enter the first name / given name of this contact."
},
@@ -659,16 +622,12 @@ class OtherContactsForm(RegistrarForm):
)
last_name = forms.CharField(
label="Last name / family name",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": "Enter the last name / family name of this contact."
},
)
title = forms.CharField(
label="Title or role in your organization",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={
"required": (
"Enter the title or role in your organization of this contact (e.g.,"
@@ -678,7 +637,6 @@ class OtherContactsForm(RegistrarForm):
)
email = forms.EmailField(
label="Email",
- label_suffix=REQUIRED_SUFFIX,
error_messages={
"invalid": (
"Enter an email address in the required format, like name@example.com."
@@ -687,8 +645,6 @@ class OtherContactsForm(RegistrarForm):
)
phone = PhoneNumberField(
label="Phone",
- label_suffix=REQUIRED_SUFFIX,
- required=True,
error_messages={"required": "Enter a phone number for this contact."},
)
@@ -744,17 +700,10 @@ class RequirementsForm(RegistrarForm):
"I read and agree to the requirements for registering "
"and operating .gov domains."
),
- required=False, # use field validation to enforce this
- )
-
- def clean_is_policy_acknowledged(self):
- """This box must be checked to proceed but offer a clear error."""
- # already converted to a boolean
- is_acknowledged = self.cleaned_data["is_policy_acknowledged"]
- if not is_acknowledged:
- raise forms.ValidationError(
+ error_messages={
+ "required": (
"Check the box if you read and agree to the requirements for"
- " registering and operating .gov domains.",
- code="invalid",
+ " registering and operating .gov domains."
)
- return is_acknowledged
+ },
+ )
diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py
index e05f2fda4..eb89cd387 100644
--- a/src/registrar/models/domain.py
+++ b/src/registrar/models/domain.py
@@ -92,7 +92,7 @@ class Domain(TimeStampedModel):
# a domain name is alphanumeric or hyphen, up to 63 characters, doesn't
# begin or end with a hyphen, followed by a TLD of 2-6 alphabetic characters
- DOMAIN_REGEX = re.compile(r"^(?!-)[A-Za-z0-9-]{1,63}(? bool:
diff --git a/src/registrar/models/domain_application.py b/src/registrar/models/domain_application.py
index 7db923a92..7924b2d2f 100644
--- a/src/registrar/models/domain_application.py
+++ b/src/registrar/models/domain_application.py
@@ -120,7 +120,6 @@ class DomainApplication(TimeStampedModel):
LEGISLATIVE = "legislative", "Legislative"
AGENCIES = [
- "",
"Administrative Conference of the United States",
"Advisory Council on Historic Preservation",
"American Battle Monuments Commission",
diff --git a/src/registrar/templates/application_anything_else.html b/src/registrar/templates/application_anything_else.html
index 3893101d6..aba7ded8a 100644
--- a/src/registrar/templates/application_anything_else.html
+++ b/src/registrar/templates/application_anything_else.html
@@ -1,23 +1,14 @@
{% extends 'application_form.html' %}
-{% load widget_tweaks %}
-
-{% block form_content %}
-
-
Is there anything else we should know about your domain request?
+ Who is the authorizing official for your organization?
+
-
Who is the authorizing official for your organization?
-
-
-
Your authorizing official is the person within your organization who can authorize your domain request. This is generally the highest ranking or highest elected official in your organization. Read more about who can serve as an authorizing official.
-
+
Your authorizing official is the person within your organization who can authorize
+ your domain request. This is generally the highest ranking or highest elected official
+ in your organization. Read more about who can serve as an
+ authorizing official.
{% include "includes/ao_example.html" %}
-
We’ll contact your authorizing official to let them know that you made this request and to double check that they approve it.
-
+
We’ll contact your authorizing official to let them know that you made this request
+ and to double check that they approve it.
+{% endblock %}
-{% include "includes/required_fields.html" %}
-
-
-{% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/src/registrar/templates/application_current_sites.html b/src/registrar/templates/application_current_sites.html
index 2d858353f..a99da2095 100644
--- a/src/registrar/templates/application_current_sites.html
+++ b/src/registrar/templates/application_current_sites.html
@@ -1,31 +1,24 @@
{% extends 'application_form.html' %}
-{% load widget_tweaks field_helpers %}
{% load static %}
+{% load field_helpers %}
-{% block form_content %}
-
-
We’d like to contact other employees with administrative or technical
+ responsibilities in your organization. For example, they could be involved in
+ managing your organization or its technical infrastructure. This information will
+ help us assess your eligibility and understand the purpose of the .gov domain. These
+ contacts should be in addition to you and your authorizing official.
+{% endblock %}
-
We’d like to contact other employees with administrative or technical responsibilities in your organization. For example, they could be involved in managing your organization or its technical infrastructure. This information will help us assess your eligibility and understand the purpose of the .gov domain. These contacts should be in addition to you and your authorizing official.
-{% include "includes/required_fields.html" %}
-
+{% block form_fields %}
{% csrf_token %}
{{ forms.0.management_form }}
{# forms.0 is a formset and this iterates over its forms #}
{% for form in forms.0.forms %}
{% endfor %}
-
-
-
-
- {{ block.super }}
-
-
-
-{% endblock %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/registrar/templates/application_purpose.html b/src/registrar/templates/application_purpose.html
index c2ed0a8ba..326358c5a 100644
--- a/src/registrar/templates/application_purpose.html
+++ b/src/registrar/templates/application_purpose.html
@@ -1,41 +1,21 @@
{% extends 'application_form.html' %}
-{% load widget_tweaks %}
+{% load field_helpers %}
-{% block form_content %}
-
-
-
.Gov domain names are intended for use on the internet. They should be registered with an intent to deploy services, not simply to reserve a name. .Gov domains should not be registered for primarily internal use.
-
Describe the reason for your domain request. Explain how you plan to use this domain. Will you use it for a website and/or email? Are you moving your website from another top-level domain (like .com or .org)? Read about activities that are prohibited on .gov domains.
-
This question is required.
-
-
-
-
- {% csrf_token %}
-
-
- {% with field=forms.0.purpose %}
- {% if field.errors %}
-
- {% else %}
- {{ field|add_label_class:"usa-label usa-sr-only" }}
- {{ field|add_class:"usa-textarea usa-character-count__field"|attr:"aria-describedby:instructions"|attr:"maxlength=500" }}
- {% endif %}
- {% endwith %}
- You can enter up to 500 characters
-
-
-
- {{ block.super }}
-
-
+{% block form_instructions %}
+
.Gov domain names are intended for use on the internet. They should be registered
+ with an intent to deploy services, not simply to reserve a name. .Gov domains should
+ not be registered for primarily internal use.
+
Describe the reason for your domain request. Explain how you plan to use this
+ domain. Will you use it for a website and/or email? Are you moving your website from
+ another top-level domain (like .com or .org)? Read about activities that
+ are prohibited on .gov domains.
The .gov domain exists to support a broad diversity of government missions and
+ public initiatives. Generally, the .gov registry does not review or audit how
+ government organizations use their domains. However, misuse of an individual .gov
+ domain can reflect upon the integrity of the entire .gov space. There are categories
+ of misuse that are statutorily prohibited or abusive in nature.
-
The .gov domain exists to support a broad diversity of government missions and public initiatives. Generally, the .gov registry does not review or audit how government organizations use their domains. However, misuse of an individual .gov domain can reflect upon the integrity of the entire .gov space. There are categories of misuse that are statutorily prohibited or abusive in nature.
+
Prohibited activities for .gov domains
-
Prohibited activities for .gov domains
+
Commercial purposes
-
Commercial purposes
-
A .gov domain must not be used for commercial purposes, such as advertising benefitting private individuals or entities.
+
A .gov domain must not be used for commercial purposes, such as advertising
+ benefitting private individuals or entities.
-
Political campaigns
-
A .gov domain must not be used for political campaigns.
+
Political campaigns
-
Illegal content
-
A .gov domain must not be used to distribute or promote material whose distribution violates applicable law.
+
A .gov domain must not be used for political campaigns.
-
Malicious cyber activity
-
.Gov is a trusted and safe space. .Gov domains must not distribute malware, host open redirects, or otherwise engage in malicious cyber activity.
+
Illegal content
+
A .gov domain must not be used to distribute or promote material whose distribution
+ violates applicable law.
-
Required activities for .gov domain registrants
+
Malicious cyber activity
-
Keep your contact information updated
-
As a .gov domain registrant, maintain current and accurate contact information in the .gov registrar. We strongly recommend that you create and use a security contact.
+
.Gov is a trusted and safe space. .Gov domains must not distribute malware, host
+ open redirects, or otherwise engage in malicious cyber activity.
-
Be responsive if we contact you
-
Registrants should respond in a timely manner to communications about required and prohibited activities.
+
Required activities for .gov domain registrants
+
Keep your contact information updated
-
Domains can be suspended or terminated for violations
-
The .gov program may need to suspend or terminate a domain registration for violations. Registrants should respond in a timely manner to communications about prohibited activities.
-
When we discover a violation, we will make reasonable efforts to contact a registrant, including:
-
-
Emails to domain contacts
-
Phone calls to domain contacts
-
Email or phone call to the authorizing official
-
Emails or phone calls to the government organization, a parent organization, or affiliated entities
-
-
+
As a .gov domain registrant, maintain current and accurate contact information in the
+ .gov registrar. We strongly recommend that you create and use a security contact.
-
We understand the critical importance of the availability of .gov domains. Suspending or terminating a .gov domain is reserved only for prolonged, unresolved serious violations where the registrant is non-responsive. We will make extensive efforts to contact registrants and to identify potential solutions, and will make reasonable accommodations for remediation timelines proportional to the severity of the issue.
+
Be responsive if we contact you
-
Requirements for authorizing officials
+
Registrants should respond in a timely manner to communications about required and
+ prohibited activities.
-
Your authorizing official is the person within your organization who can authorize your domain request. This is generally the highest ranking or highest elected official in your organization.
+
Domains can be suspended or terminated for violations
-
Executive branch federal agencies
+
The .gov program may need to suspend or terminate a domain registration for
+ violations. Registrants should respond in a timely manner to communications about
+ prohibited activities.
-
Domain requests from executive branch agencies must be authorized by CIOs or agency heads.
+
When we discover a violation, we will make reasonable efforts to contact a
+ registrant, including:
+
+
Emails to domain contacts
+
Phone calls to domain contacts
+
Email or phone call to the authorizing official
+
Emails or phone calls to the government organization, a parent organization,
+ or affiliated entities
+
+
-
Domain requests from executive branch agencies are subject to guidance issued by the U.S. Office of Management and Budget.
+
We understand the critical importance of the availability of .gov domains.
+ Suspending or terminating a .gov domain is reserved only for prolonged, unresolved
+ serious violations where the registrant is non-responsive. We will make extensive
+ efforts to contact registrants and to identify potential solutions, and will make
+ reasonable accommodations for remediation timelines proportional to the severity of
+ the issue.
-
Judicial branch federal agencies
+
Requirements for authorizing officials
-
Domain requests for judicial branch agencies, except the U.S. Supreme Court, must be authorized by the director or CIO of the Administrative Office (AO) of the United States Courts.
+
Your authorizing official is the person within your organization who can authorize
+ your domain request. This is generally the highest ranking or highest elected official
+ in your organization.
-
Domain requests from the U.S. Supreme Court must be authorized by the director of information technology for the U.S. Supreme Court.
+
Executive branch federal agencies
-
Legislative branch federal agencies
+
Domain requests from executive branch agencies must be authorized by CIOs or agency
+ heads.
-
U.S. Senate
+
Domain requests from executive branch agencies are subject to guidance issued by
+ the U.S. Office of Management and Budget.
-
Domain requests from the U.S. Senate must come from the Senate Sergeant at Arms.
+
Judicial branch federal agencies
-
U.S. House of Representatives
+
Domain requests for judicial branch agencies, except the U.S. Supreme Court, must
+ be authorized by the director or CIO of the Administrative Office (AO) of the United
+ States Courts.
-
Domain requests from the U.S. House of Representatives must come from the House Chief Administrative Officer.
+
Domain requests from the U.S. Supreme Court must be authorized by the director of
+ information technology for the U.S. Supreme Court.
-
Other legislative branch agencies
+
Legislative branch federal agencies
-
Domain requests from legislative branch agencies must come from the agency’s head or CIO.
+
U.S. Senate
-
Domain requests from legislative commissions must come from the head of the commission, or the head or CIO of the parent agency, if there is one.
+
Domain requests from the U.S. Senate must come from the Senate Sergeant at Arms.
-
Interstate
+
U.S. House of Representatives
-
Domain requests from interstate organizations must be authorized by the highest-ranking executive (president, director, chair, or equivalent) or one of the state’s governors or CIOs.
+
Domain requests from the U.S. House of Representatives must come from the House
+ Chief Administrative Officer.
-
U.S. states and territories
+
Other legislative branch agencies
-
States and territories: executive branch
+
Domain requests from legislative branch agencies must come from the agency’s head
+ or CIO.
-
Domain requests from states and territories must be authorized by the governor or the state CIO.
+
Domain requests from legislative commissions must come from the head of the
+ commission, or the head or CIO of the parent agency, if there is one.
-
States and territories: judicial and legislative branches
+
Interstate
-
Domain requests from state legislatures and courts must be authorized by an agency’s CIO or highest-ranking executive.
+
Domain requests from interstate organizations must be authorized by the
+ highest-ranking executive (president, director, chair, or equivalent) or one of the
+ state’s governors or CIOs.
-
Tribal governments
+
U.S. states and territories
-
Domain requests from federally-recognized tribal governments must be authorized by tribal chiefs as noted by the Bureau of Indian Affairs.
+
States and territories: executive branch
-
Counties
+
Domain requests from states and territories must be authorized by the governor or
+ the state CIO.
-
Domain requests from counties must be authorized by the chair of the county commission or the equivalent highest elected official.
+
States and territories: judicial and legislative branches
-
Cities
+
Domain requests from state legislatures and courts must be authorized by an
+ agency’s CIO or highest-ranking executive.
-
Domain requests from cities must be authorized by the mayor or the equivalent highest elected official.
+
Tribal governments
-
Special districts
+
Domain requests from federally-recognized tribal governments must be authorized by
+ tribal chiefs as noted by the
+ Bureau of Indian
+ Affairs.
-
Domain requests from special districts must be authorized by the highest-ranking executive (president, director, chair, or equivalent) or state CIOs for state-based organizations.
+
Counties
-
School districts
+
Domain requests from counties must be authorized by the chair of the county
+ commission or the equivalent highest elected official.
-
Domain requests from school district governments must be authorized by the highest-ranking executive (the chair of a school district’s board or a superintendent).
+
Cities
-
Requirements for .gov domain names
-
.Gov domains must:
-
-
Be available
-
Be unique
-
Relate to your organization’s name, location, and/or services
-
Be clear to the general public. Your domain name must not be easily confused with other organizations.
-
+
Domain requests from cities must be authorized by the mayor or the equivalent
+ highest elected official.
+
Special districts
-
HSTS preloading
-
The .gov program will preload all newly registered .gov domains for HTTP Strict Transport Security (HSTS).
-
HSTS is a simple and widely-supported standard that protects visitors by ensuring that their browsers always connect to a website over HTTPS. HSTS removes the need to redirect users from http:// to https:// URLs. (This redirection is a security risk that HSTS eliminates.)
-
HSTS preloading impacts web traffic only. Once a domain is on the HSTS preload list, modern web browsers will enforce HTTPS connections for all websites hosted on the .gov domain. Users will not be able to click through warnings to reach a site. Non-web uses of .gov (email, VPN, APIs, etc.) are not affected.
+
Domain requests from special districts must be authorized by the highest-ranking
+ executive (president, director, chair, or equivalent) or state CIOs for state-based
+ organizations.
+
School districts
-
Acknowledgement of .gov domain requirements
+
Domain requests from school district governments must be authorized by the highest-ranking
+ executive (the chair of a school district’s board or a superintendent).
-
This question is required.
+
Requirements for .gov domain names
-
-
- {% csrf_token %}
+
.Gov domains must:
+
+
Be available
+
Be unique
+
Relate to your organization’s name, location, and/or services
+
Be clear to the general public. Your domain name must not be easily confused
+ with other organizations.
+
+
- {% if forms.0.is_policy_acknowledged.errors %}
-
- {% for error in forms.0.is_policy_acknowledged.errors %}
-
- {{ error }}
-
- {% endfor %}
-
The .gov program will preload all newly registered .gov domains for HTTP Strict
+ Transport Security (HSTS).
-
+
HSTS is a simple and widely-supported standard that protects visitors by ensuring
+ that their browsers always connect to a website over HTTPS. HSTS removes the need to
+ redirect users from http:// to https:// URLs. (This redirection is a security risk
+ that HSTS eliminates.)
+
HSTS preloading impacts web traffic only. Once a domain is on the HSTS preload
+ list, modern web browsers will enforce HTTPS connections for all websites hosted on
+ the .gov domain. Users will not be able to click through warnings to reach a site.
+ Non-web uses of .gov (email, VPN, APIs, etc.) are not affected.
-
-{% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/src/registrar/templates/application_security_email.html b/src/registrar/templates/application_security_email.html
index f909a024b..9a240c264 100644
--- a/src/registrar/templates/application_security_email.html
+++ b/src/registrar/templates/application_security_email.html
@@ -1,30 +1,15 @@
{% extends 'application_form.html' %}
-{% load widget_tweaks %}
-{% load static %}
-
-{% block form_content %}
-
-
We strongly recommend that you provide a security email. This email will allow the public to report observed or suspected security issues on your domain. Security emails are made public. We recommend using an alias, like security@<domain.gov>.
We strongly recommend that you provide a security email. This email will allow the
+ public to report observed or suspected security issues on your domain.
+ Security emails are made public. We recommend using an alias, like
+ security@<domain.gov>.
We’ll use the following information to contact you about your domain request and,
+ once your request is approved, about managing your domain.
-
-
We’ll use the following information to contact you about your domain request and, once your request is approved, about managing your domain.
+
If you’d like us to use a different name, email, or phone number you can make those
+ changes below. Changing your contact information here won’t affect your login.gov
+ account information.
-
If you’d like us to use a different name, email, or phone number you can make those changes below. Changing your contact information here won’t affect your login.gov account information.
+
The contact information you provide here won’t be public and will only be used for
+ the .gov registry.
+{% endblock %}
-
The contact information you provide here won’t be public and will only be used for the .gov registry.
-
-{% include "includes/required_fields.html" %}
-
-
-
-{% endblock %}
+{% endblock %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/label.html b/src/registrar/templates/django/forms/label.html
new file mode 100644
index 000000000..9a1b6ba6e
--- /dev/null
+++ b/src/registrar/templates/django/forms/label.html
@@ -0,0 +1,9 @@
+<{{ label_tag }}
+ class="{% if label_classes %} {{ label_classes }}{% endif %}"
+ {% if not field.use_fieldset %}for="{{ widget.attrs.id }}"{% endif %}
+>
+{{ field.label }}
+{% if widget.attrs.required %}
+ *
+{% endif %}
+{{ label_tag }}>
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/attrs.html b/src/registrar/templates/django/forms/widgets/attrs.html
new file mode 100644
index 000000000..78dcb5070
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/attrs.html
@@ -0,0 +1,3 @@
+{% for name, value in widget.attrs.items %}{% if value is not False %}
+ {{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"
+{% endif %}{% endif %}{% endfor %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/checkbox.html b/src/registrar/templates/django/forms/widgets/checkbox.html
new file mode 100644
index 000000000..7af5802a2
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/checkbox.html
@@ -0,0 +1,3 @@
+{% with uswds_input_class="usa-checkbox__input" %}
+ {% include "django/forms/widgets/input.html" %}
+{% endwith %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/email.html b/src/registrar/templates/django/forms/widgets/email.html
new file mode 100644
index 000000000..9d266b8a9
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/email.html
@@ -0,0 +1,3 @@
+{% with uswds_input_class="usa-input" %}
+ {% include "django/forms/widgets/input.html" %}
+{% endwith %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/hidden.html b/src/registrar/templates/django/forms/widgets/hidden.html
new file mode 100644
index 000000000..1f4676a22
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/hidden.html
@@ -0,0 +1 @@
+{% include "django/forms/widgets/input.html" %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/input.html b/src/registrar/templates/django/forms/widgets/input.html
new file mode 100644
index 000000000..ba287df3a
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/input.html
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/multiple_input.html b/src/registrar/templates/django/forms/widgets/multiple_input.html
new file mode 100644
index 000000000..90c241366
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/multiple_input.html
@@ -0,0 +1,20 @@
+
+ {% for group, options, index in widget.optgroups %}
+ {% if group %}
{% endif %}
+ {% for option in options %}
+
+
+ {% endfor %}
+ {% if group %}
{% endif %}
+ {% endfor %}
+
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/number.html b/src/registrar/templates/django/forms/widgets/number.html
new file mode 100644
index 000000000..9d266b8a9
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/number.html
@@ -0,0 +1,3 @@
+{% with uswds_input_class="usa-input" %}
+ {% include "django/forms/widgets/input.html" %}
+{% endwith %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/password.html b/src/registrar/templates/django/forms/widgets/password.html
new file mode 100644
index 000000000..9d266b8a9
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/password.html
@@ -0,0 +1,3 @@
+{% with uswds_input_class="usa-input" %}
+ {% include "django/forms/widgets/input.html" %}
+{% endwith %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/radio.html b/src/registrar/templates/django/forms/widgets/radio.html
new file mode 100644
index 000000000..11881e42a
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/radio.html
@@ -0,0 +1,3 @@
+{% with uswds_input_class="usa-radio" %}
+ {% include "django/forms/widgets/multiple_input.html" %}
+{% endwith %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/radio_option.html b/src/registrar/templates/django/forms/widgets/radio_option.html
new file mode 100644
index 000000000..a10ecaea1
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/radio_option.html
@@ -0,0 +1 @@
+{% include "django/forms/widgets/input_option.html" %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/regionalphonenumber.html b/src/registrar/templates/django/forms/widgets/regionalphonenumber.html
new file mode 100644
index 000000000..9d266b8a9
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/regionalphonenumber.html
@@ -0,0 +1,3 @@
+{% with uswds_input_class="usa-input" %}
+ {% include "django/forms/widgets/input.html" %}
+{% endwith %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/select.html b/src/registrar/templates/django/forms/widgets/select.html
new file mode 100644
index 000000000..cc62eb91d
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/select.html
@@ -0,0 +1,14 @@
+
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/select_option.html b/src/registrar/templates/django/forms/widgets/select_option.html
new file mode 100644
index 000000000..c8405eee2
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/select_option.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/text.html b/src/registrar/templates/django/forms/widgets/text.html
new file mode 100644
index 000000000..9d266b8a9
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/text.html
@@ -0,0 +1,3 @@
+{% with uswds_input_class="usa-input" %}
+ {% include "django/forms/widgets/input.html" %}
+{% endwith %}
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/textarea.html b/src/registrar/templates/django/forms/widgets/textarea.html
new file mode 100644
index 000000000..068f15399
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/textarea.html
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/src/registrar/templates/django/forms/widgets/url.html b/src/registrar/templates/django/forms/widgets/url.html
new file mode 100644
index 000000000..9d266b8a9
--- /dev/null
+++ b/src/registrar/templates/django/forms/widgets/url.html
@@ -0,0 +1,3 @@
+{% with uswds_input_class="usa-input" %}
+ {% include "django/forms/widgets/input.html" %}
+{% endwith %}
\ No newline at end of file
diff --git a/src/registrar/templates/includes/input_with_errors.html b/src/registrar/templates/includes/input_with_errors.html
index 4859c8617..54ae475bf 100644
--- a/src/registrar/templates/includes/input_with_errors.html
+++ b/src/registrar/templates/includes/input_with_errors.html
@@ -5,33 +5,70 @@ error messages, if necessary.
{% load widget_tweaks %}
-{% if field.errors %}
-