Product Attributes with Optional Attribute Options via Relation Widget

Hello!

I’m trying to set up some basic product attributes/options via the config.yml file using Netlify CMS.

Currently, the following lets a user create product attributes as well as options for each attribute respectively. It also allows a user to add attributes to a product. I’m trying to figure out how to allow a user to then add any or all of the options associated with the added attribute.

Example: User creates a ‘Size’ product attribute and adds ‘S’, ‘M’, ‘L’, ‘XL’, and ‘2XL’ as options. In the product, the user adds the ‘Size’ attribute. The user should now be able to select/add the options they want for that product’s attribute.

Is this possible?

- label: Products
    label_singular: Product
    name: products
    folder: content/products
    create: true
    fields:
      - {
          label: "Template Key",
          name: template-key,
          widget: hidden,
          default: "product-page",
        }
      - { label: "Slug", name: slug, widget: "string" }
      - { label: "Title", name: title, widget: "string" }
      - { label: "SKU", name: sku, widget: "string" }
      - {
          label: "Attributes",
          name: attributes,
          widget: list,
          fields:
            [
              {
                label: "Attribute",
                name: attribute,
                widget: "relation",
                collection: product-attributes,
                searchFields: [title],
                valueField: title,
                displayFields: [title],
              },
            ],
        }
      - { label: "Price", name: price, widget: "number" }
      - { label: "Image", name: image, widget: "image" }
      - { label: "Description", name: description, widget: "markdown" }
  - label: "Product Attributes"
    label_singular: "Product Attribute"
    name: product-attributes
    folder: content/product-attributes
    create: true
    fields:
      - { label: "Title", name: title, widget: "string" }
      - {
          label: Option,
          name: option,
          widget: list,
          fields: [{ label: "Title", name: title, widget: string }],
        }

Hi @taylor, we recently added a feature that allows using a wildcard character * to expand lists.

I believe this will get you very close to what you need:

{
  label: 'Attribute',
  name: attribute,
  widget: 'relation',
  collection: product-attributes,
  searchFields: [option.*.title],
  valueField: option.*.title,
  displayFields: [title, option.*.title],
},

Result:

The only issue that since valueField: option.*.title is only the title of the option, the resulting file will be:

attributes:
  - attribute: S

Which means those values should be unique.

@erez, thanks for getting back to me!

This is very helpful. It’s very close, not perfect, but close.

One of the issues I’m having with this solution is what gets returned when I query. I’m able to get a list of the Attribute Option Title(s) but not the Attribute Title. Here’s an example:

{
  "data": {
    "allMarkdownRemark": {
      "nodes": [
        {
          "frontmatter": {
            "attributes": [
              {
                "attribute": "Black"
              },
              {
                "attribute": "Dark Green"
              },
              {
                "attribute": "Navy"
              },
              {
                "attribute": "Yellow"
              }
            ]
          }
        },
      ]
    }
  }
}

I need to know the name of the Attribute these options are assigned to. In this case, it would be “Color”. I’m creating a dropdown that will be dependant on the attribute title (i.e. “Select a Color” or “Select a Size”).

I messed with the wildcard a bit but couldn’t figure out a solution. Any way to include that?

Bonus: Is there a way to customize the displayFields to say: “Color: Black” (added semicolon)

Thanks for the help!

Hi @taylor,

We do support string templates in the relation widget, meaning you could do:

valueField: "{{fields.title}}____{{fields.option}}"
displayFields: ["{{fields.title}}; {{fields.option}}"]

to create any type of field formatting, but unfortunately that doesn’t work with wildcards yet.

Do you mind opening an issue for it?

Thanks