diff --git a/.changes/unreleased/BUG FIXES-20240410-154619.yaml b/.changes/unreleased/BUG FIXES-20240410-154619.yaml
new file mode 100644
index 00000000..4302f892
--- /dev/null
+++ b/.changes/unreleased/BUG FIXES-20240410-154619.yaml
@@ -0,0 +1,6 @@
+kind: BUG FIXES
+body: 'generate: fixed a bug where incorrect attribute titles were being generated
+ for certain nested schemas'
+time: 2024-04-10T15:46:19.65146-04:00
+custom:
+ Issue: "350"
diff --git a/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_nested_blocks.txtar b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_nested_blocks.txtar
new file mode 100644
index 00000000..ff93eef6
--- /dev/null
+++ b/cmd/tfplugindocs/testdata/scripts/schema-json/generate/framework_provider_success_nested_blocks.txtar
@@ -0,0 +1,744 @@
+# Copyright (c) HashiCorp, Inc.
+# SPDX-License-Identifier: MPL-2.0
+
+# Successful run of tfplugindocs on a Framework provider with a resource schema that contains nested types
+[!unix] skip
+exec tfplugindocs --provider-name=terraform-provider-scaffolding --providers-schema=schema.json
+cmp stdout expected-output.txt
+cmp docs/index.md expected-index.md
+cmp docs/resources/example.md expected-resource.md
+
+-- expected-output.txt --
+rendering website for provider "terraform-provider-scaffolding" (as "terraform-provider-scaffolding")
+exporting schema from JSON file
+getting provider schema
+generating missing templates
+generating missing resource content
+generating new template for "scaffolding_example"
+generating missing data source content
+generating missing function content
+generating missing provider content
+generating new template for "terraform-provider-scaffolding"
+rendering static website
+cleaning rendered website dir
+rendering templated website to static markdown
+rendering "index.md.tmpl"
+rendering "resources/example.md.tmpl"
+-- expected-index.md --
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "scaffolding Provider"
+subcategory: ""
+description: |-
+ Example provider
+---
+
+# scaffolding Provider
+
+Example provider
+
+
+
+
+## Schema
+
+### Optional
+
+- `endpoint` (String) Example provider attribute
+-- expected-resource.md --
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "scaffolding_example Resource - terraform-provider-scaffolding"
+subcategory: ""
+description: |-
+ A certificate issued via a private certificate authority
+---
+
+# scaffolding_example (Resource)
+
+A certificate issued via a private certificate authority
+
+
+
+
+## Schema
+
+### Required
+
+- `certificate_authority_arn` (String)
+- `certificate_signing_request` (String) The certificate signing request (CSR) for the Certificate.
+- `signing_algorithm` (String) The name of the algorithm that will be used to sign the Certificate.
+- `validity` (Attributes) Validity for a certificate. (see [below for nested schema](#nestedatt--validity))
+
+### Optional
+
+- `api_passthrough` (Attributes) Structure that specifies fields to be overridden in a certificate at the time of issuance. These requires an API Passthrough template be used or they will be ignored. (see [below for nested schema](#nestedatt--api_passthrough))
+- `template_arn` (String)
+- `validity_not_before` (Attributes) Validity for a certificate. (see [below for nested schema](#nestedatt--validity_not_before))
+
+### Read-Only
+
+- `arn` (String)
+- `certificate` (String) The issued certificate in base 64 PEM-encoded format.
+- `id` (String) Uniquely identifies the resource.
+
+
+### Nested Schema for `validity`
+
+Required:
+
+- `type` (String)
+- `value` (Number)
+
+
+
+### Nested Schema for `api_passthrough`
+
+Optional:
+
+- `extensions` (Attributes) Structure that contains X.500 extensions for a Certificate. (see [below for nested schema](#nestedatt--api_passthrough--extensions))
+- `subject` (Attributes) Structure that contains X.500 distinguished name information. (see [below for nested schema](#nestedatt--api_passthrough--subject))
+
+
+### Nested Schema for `api_passthrough.extensions`
+
+Optional:
+
+- `certificate_policies` (Attributes List) (see [below for nested schema](#nestedatt--api_passthrough--extensions--certificate_policies))
+- `extended_key_usage` (Attributes List) (see [below for nested schema](#nestedatt--api_passthrough--extensions--extended_key_usage))
+- `key_usage` (Attributes) Structure that contains X.509 KeyUsage information. (see [below for nested schema](#nestedatt--api_passthrough--extensions--key_usage))
+- `subject_alternative_names` (Attributes List) (see [below for nested schema](#nestedatt--api_passthrough--extensions--subject_alternative_names))
+
+
+### Nested Schema for `api_passthrough.extensions.certificate_policies`
+
+Required:
+
+- `cert_policy_id` (String) String that contains X.509 ObjectIdentifier information.
+
+Optional:
+
+- `policy_qualifiers` (Attributes List) (see [below for nested schema](#nestedatt--api_passthrough--extensions--certificate_policies--policy_qualifiers))
+
+
+### Nested Schema for `api_passthrough.extensions.certificate_policies.policy_qualifiers`
+
+Required:
+
+- `policy_qualifier_id` (String)
+- `qualifier` (Attributes) Structure that contains a X.509 policy qualifier. (see [below for nested schema](#nestedatt--api_passthrough--extensions--certificate_policies--policy_qualifiers--qualifier))
+
+
+### Nested Schema for `api_passthrough.extensions.certificate_policies.policy_qualifiers.qualifier`
+
+Required:
+
+- `cps_uri` (String)
+
+
+
+
+
+### Nested Schema for `api_passthrough.extensions.extended_key_usage`
+
+Optional:
+
+- `extended_key_usage_object_identifier` (String) String that contains X.509 ObjectIdentifier information.
+- `extended_key_usage_type` (String)
+
+
+
+### Nested Schema for `api_passthrough.extensions.key_usage`
+
+Optional:
+
+- `crl_sign` (Boolean)
+- `data_encipherment` (Boolean)
+- `decipher_only` (Boolean)
+- `digital_signature` (Boolean)
+- `encipher_only` (Boolean)
+- `key_agreement` (Boolean)
+- `key_cert_sign` (Boolean)
+- `key_encipherment` (Boolean)
+- `non_repudiation` (Boolean)
+
+
+
+### Nested Schema for `api_passthrough.extensions.subject_alternative_names`
+
+Optional:
+
+- `directory_name` (Attributes) Structure that contains X.500 distinguished name information. (see [below for nested schema](#nestedatt--api_passthrough--extensions--subject_alternative_names--directory_name))
+- `dns_name` (String) String that contains X.509 DnsName information.
+- `edi_party_name` (Attributes) Structure that contains X.509 EdiPartyName information. (see [below for nested schema](#nestedatt--api_passthrough--extensions--subject_alternative_names--edi_party_name))
+- `ip_address` (String) String that contains X.509 IpAddress information.
+- `other_name` (Attributes) Structure that contains X.509 OtherName information. (see [below for nested schema](#nestedatt--api_passthrough--extensions--subject_alternative_names--other_name))
+- `registered_id` (String) String that contains X.509 ObjectIdentifier information.
+- `rfc_822_name` (String) String that contains X.509 Rfc822Name information.
+- `uniform_resource_identifier` (String) String that contains X.509 UniformResourceIdentifier information.
+
+
+### Nested Schema for `api_passthrough.extensions.subject_alternative_names.directory_name`
+
+Optional:
+
+- `common_name` (String)
+- `country` (String)
+- `distinguished_name_qualifier` (String)
+- `generation_qualifier` (String)
+- `given_name` (String)
+- `initials` (String)
+- `locality` (String)
+- `organization` (String)
+- `organizational_unit` (String)
+- `pseudonym` (String)
+- `serial_number` (String)
+- `state` (String)
+- `surname` (String)
+- `title` (String)
+
+
+
+### Nested Schema for `api_passthrough.extensions.subject_alternative_names.edi_party_name`
+
+Required:
+
+- `name_assigner` (String)
+- `party_name` (String)
+
+
+
+### Nested Schema for `api_passthrough.extensions.subject_alternative_names.other_name`
+
+Required:
+
+- `type_id` (String) String that contains X.509 ObjectIdentifier information.
+- `value` (String)
+
+
+
+
+
+### Nested Schema for `api_passthrough.subject`
+
+Optional:
+
+- `common_name` (String)
+- `country` (String)
+- `distinguished_name_qualifier` (String)
+- `generation_qualifier` (String)
+- `given_name` (String)
+- `initials` (String)
+- `locality` (String)
+- `organization` (String)
+- `organizational_unit` (String)
+- `pseudonym` (String)
+- `serial_number` (String)
+- `state` (String)
+- `surname` (String)
+- `title` (String)
+
+
+
+
+### Nested Schema for `validity_not_before`
+
+Required:
+
+- `type` (String)
+- `value` (Number)
+-- schema.json --
+{
+ "format_version": "1.0",
+ "provider_schemas": {
+ "registry.terraform.io/hashicorp/scaffolding": {
+ "provider": {
+ "version": 0,
+ "block": {
+ "attributes": {
+ "endpoint": {
+ "type": "string",
+ "description": "Example provider attribute",
+ "description_kind": "markdown",
+ "optional": true
+ }
+ },
+ "description": "Example provider",
+ "description_kind": "markdown"
+ }
+ },
+ "resource_schemas": {
+ "scaffolding_example": {
+ "block": {
+ "attributes": {
+ "api_passthrough": {
+ "computed": true,
+ "description": "Structure that specifies fields to be overridden in a certificate at the time of issuance. These requires an API Passthrough template be used or they will be ignored.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "extensions": {
+ "description": "Structure that contains X.500 extensions for a Certificate.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "certificate_policies": {
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "cert_policy_id": {
+ "description": "String that contains X.509 ObjectIdentifier information.",
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "policy_qualifiers": {
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "policy_qualifier_id": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "qualifier": {
+ "description": "Structure that contains a X.509 policy qualifier.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "cps_uri": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "required": true
+ }
+ },
+ "nesting_mode": "list"
+ },
+ "optional": true
+ }
+ },
+ "nesting_mode": "list"
+ },
+ "optional": true
+ },
+ "extended_key_usage": {
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "extended_key_usage_object_identifier": {
+ "description": "String that contains X.509 ObjectIdentifier information.",
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "extended_key_usage_type": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ }
+ },
+ "nesting_mode": "list"
+ },
+ "optional": true
+ },
+ "key_usage": {
+ "description": "Structure that contains X.509 KeyUsage information.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "crl_sign": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ },
+ "data_encipherment": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ },
+ "decipher_only": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ },
+ "digital_signature": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ },
+ "encipher_only": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ },
+ "key_agreement": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ },
+ "key_cert_sign": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ },
+ "key_encipherment": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ },
+ "non_repudiation": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "bool"
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "optional": true
+ },
+ "subject_alternative_names": {
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "directory_name": {
+ "description": "Structure that contains X.500 distinguished name information.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "common_name": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "country": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "distinguished_name_qualifier": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "generation_qualifier": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "given_name": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "initials": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "locality": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "organization": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "organizational_unit": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "pseudonym": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "serial_number": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "state": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "surname": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "title": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "optional": true
+ },
+ "dns_name": {
+ "description": "String that contains X.509 DnsName information.",
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "edi_party_name": {
+ "description": "Structure that contains X.509 EdiPartyName information.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "name_assigner": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "party_name": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "optional": true
+ },
+ "ip_address": {
+ "description": "String that contains X.509 IpAddress information.",
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "other_name": {
+ "description": "Structure that contains X.509 OtherName information.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "type_id": {
+ "description": "String that contains X.509 ObjectIdentifier information.",
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "optional": true
+ },
+ "registered_id": {
+ "description": "String that contains X.509 ObjectIdentifier information.",
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "rfc_822_name": {
+ "description": "String that contains X.509 Rfc822Name information.",
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "uniform_resource_identifier": {
+ "description": "String that contains X.509 UniformResourceIdentifier information.",
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ }
+ },
+ "nesting_mode": "list"
+ },
+ "optional": true
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "optional": true
+ },
+ "subject": {
+ "description": "Structure that contains X.500 distinguished name information.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "common_name": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "country": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "distinguished_name_qualifier": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "generation_qualifier": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "given_name": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "initials": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "locality": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "organization": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "organizational_unit": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "pseudonym": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "serial_number": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "state": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "surname": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "title": {
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "optional": true
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "optional": true
+ },
+ "arn": {
+ "computed": true,
+ "description_kind": "plain",
+ "type": "string"
+ },
+ "certificate": {
+ "computed": true,
+ "description": "The issued certificate in base 64 PEM-encoded format.",
+ "description_kind": "plain",
+ "type": "string"
+ },
+ "certificate_authority_arn": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "certificate_signing_request": {
+ "description": "The certificate signing request (CSR) for the Certificate.",
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "id": {
+ "computed": true,
+ "description": "Uniquely identifies the resource.",
+ "description_kind": "plain",
+ "type": "string"
+ },
+ "signing_algorithm": {
+ "description": "The name of the algorithm that will be used to sign the Certificate.",
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "template_arn": {
+ "computed": true,
+ "description_kind": "plain",
+ "optional": true,
+ "type": "string"
+ },
+ "validity": {
+ "description": "Validity for a certificate.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "type": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "number"
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "required": true
+ },
+ "validity_not_before": {
+ "computed": true,
+ "description": "Validity for a certificate.",
+ "description_kind": "plain",
+ "nested_type": {
+ "attributes": {
+ "type": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "string"
+ },
+ "value": {
+ "description_kind": "plain",
+ "required": true,
+ "type": "number"
+ }
+ },
+ "nesting_mode": "single"
+ },
+ "optional": true
+ }
+ },
+ "description": "A certificate issued via a private certificate authority",
+ "description_kind": "plain"
+ },
+ "version": 1
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/schemamd/render.go b/schemamd/render.go
index 90617d86..77e575d4 100644
--- a/schemamd/render.go
+++ b/schemamd/render.go
@@ -57,11 +57,12 @@ var (
)
type nestedType struct {
- anchorID string
- path []string
- block *tfjson.SchemaBlock
- object *cty.Type
- attrs *tfjson.SchemaNestedAttributeType
+ anchorID string
+ pathTitle string
+ path []string
+ block *tfjson.SchemaBlock
+ object *cty.Type
+ attrs *tfjson.SchemaNestedAttributeType
group groupFilter
}
@@ -87,6 +88,7 @@ func writeAttribute(w io.Writer, path []string, att *tfjson.SchemaAttribute, gro
}
anchorID := "nestedatt--" + strings.Join(path, "--")
+ pathTitle := strings.Join(path, ".")
nestedTypes := []nestedType{}
switch {
case att.AttributeNestedType != nil:
@@ -96,9 +98,10 @@ func writeAttribute(w io.Writer, path []string, att *tfjson.SchemaAttribute, gro
}
nestedTypes = append(nestedTypes, nestedType{
- anchorID: anchorID,
- path: path,
- attrs: att.AttributeNestedType,
+ anchorID: anchorID,
+ pathTitle: pathTitle,
+ path: path,
+ attrs: att.AttributeNestedType,
group: group,
})
@@ -109,9 +112,10 @@ func writeAttribute(w io.Writer, path []string, att *tfjson.SchemaAttribute, gro
}
nestedTypes = append(nestedTypes, nestedType{
- anchorID: anchorID,
- path: path,
- object: &att.AttributeType,
+ anchorID: anchorID,
+ pathTitle: pathTitle,
+ path: path,
+ object: &att.AttributeType,
group: group,
})
@@ -123,9 +127,10 @@ func writeAttribute(w io.Writer, path []string, att *tfjson.SchemaAttribute, gro
nt := att.AttributeType.ElementType()
nestedTypes = append(nestedTypes, nestedType{
- anchorID: anchorID,
- path: path,
- object: &nt,
+ anchorID: anchorID,
+ pathTitle: pathTitle,
+ path: path,
+ object: &nt,
group: group,
})
@@ -153,10 +158,12 @@ func writeBlockType(w io.Writer, path []string, block *tfjson.SchemaBlockType) (
}
anchorID := "nestedblock--" + strings.Join(path, "--")
+ pathTitle := strings.Join(path, ".")
nt := nestedType{
- anchorID: anchorID,
- path: path,
- block: block.Block,
+ anchorID: anchorID,
+ pathTitle: pathTitle,
+ path: path,
+ block: block.Block,
}
_, err = io.WriteString(w, " (see [below for nested schema](#"+anchorID+"))")
@@ -344,7 +351,7 @@ func writeNestedTypes(w io.Writer, nestedTypes []nestedType) error {
return err
}
- _, err = io.WriteString(w, "### Nested Schema for `"+strings.Join(nt.path, ".")+"`\n\n")
+ _, err = io.WriteString(w, "### Nested Schema for `"+nt.pathTitle+"`\n\n")
if err != nil {
return err
}
diff --git a/schemamd/testdata/awscc_acmpca_certificate.md b/schemamd/testdata/awscc_acmpca_certificate.md
index 2d5b36a3..73bc8880 100644
--- a/schemamd/testdata/awscc_acmpca_certificate.md
+++ b/schemamd/testdata/awscc_acmpca_certificate.md
@@ -115,7 +115,7 @@ Optional:
- `uniform_resource_identifier` (String) String that contains X.509 UniformResourceIdentifier information.
-### Nested Schema for `api_passthrough.extensions.subject_alternative_names.uniform_resource_identifier`
+### Nested Schema for `api_passthrough.extensions.subject_alternative_names.directory_name`
Optional:
@@ -136,7 +136,7 @@ Optional:
-### Nested Schema for `api_passthrough.extensions.subject_alternative_names.uniform_resource_identifier`
+### Nested Schema for `api_passthrough.extensions.subject_alternative_names.edi_party_name`
Required:
@@ -145,7 +145,7 @@ Required:
-### Nested Schema for `api_passthrough.extensions.subject_alternative_names.uniform_resource_identifier`
+### Nested Schema for `api_passthrough.extensions.subject_alternative_names.other_name`
Required: