apostrophecms / apostrophe

A full-featured, open-source content management framework built with Node.js that empowers organizations by combining in-context editing and headless architecture in a full-stack JS environment.
https://apostrophecms.com
MIT License
4.32k stars 591 forks source link

A3: Server error when nested array has a same slug as its parent array while there's also an area in the schema #4129

Open stepanjakl opened 1 year ago

stepanjakl commented 1 year ago

Hello team,

I think I discovered a pretty interesting bug. I get this server error which comes up when a very specific schema configuration is set:

Template render error: (default-page:page.html)
  Template render error: (@apostrophecms/area:area.html)
  Template render error: (test-widget:widget.html)
  Error: The doc of type undefined with the slug undefined has no field named area.
In Apostrophe 3.x areas must be part of the schema for each page or piece type.
    at Object._prettifyError (/Users/stepanjakl/Git/a3-boilerplate/node_modules/nunjucks/src/lib.js:36:11)
    ... 3 lines matching cause stack trace ...
    at extension.run (/Users/stepanjakl/Git/a3-boilerplate/node_modules/apostrophe/modules/@apostrophecms/template/index.js:445:22) {

Essentially, if there's a nested array inside an array - both with the same slug - and once an area is created, it breaks. This has been tested in a newly created A3 boilerplate project.

Here's the full code:

// widget.html

{% for item in data.widget.items %}
    {% for subItem in item.items %}
        <span>{{ subItem.title }}</span>
    {% endfor %}
    {% if item.area.items|length > 0 -%}
        {% area item, 'area' %}
    {%- endif %}
{% endfor %}
// index.js

module.exports = {
  extend: '@apostrophecms/widget-type',
  options: {
    label: 'Test widget'
  },
  fields: {
    add: {
      items: {
        label: 'Items',
        type: 'array',
        fields: {
          add: {
            title: {
              label: 'Title',
              type: 'string'
            },
            items: {
              label: 'Items',
              type: 'array',
              inline: true,
              style: 'table',
              fields: {
                add: {
                  title: {
                    label: 'Title',
                    type: 'string'
                  }
                }
              }
            },
            area: {
              label: 'Area',
              type: 'area',
              options: {
                widgets: {
                  '@apostrophecms/rich-text': {
                    toolbar: [
                      'styles',
                      '|',
                      'bold',
                      'italic',
                      'strike',
                      'link',
                      '|',
                      'bulletList',
                      'orderedList'
                    ],
                    styles: [{
                        tag: 'p',
                        label: 'Paragraph (P)'
                      },
                      {
                        tag: 'h3',
                        label: 'Heading 3 (H3)'
                      },
                      {
                        tag: 'h4',
                        label: 'Heading 4 (H4)'
                      }
                    ]
                  },
                  '@apostrophecms/image': {},
                  '@apostrophecms/video': {}
                }
              }
            }
          }
        }
      }
    }
  }
}

To Reproduce

Step by step instructions to reproduce the behavior:

  1. Create the test widget and register it
  2. Create a page with an area that includes the test widget
  3. Insert the test widget and enter some content (important to have content in the array area)
  4. See the server error

Details

Version of Node.js: v18.4.0

Server Operating System: MacOS Ventura 13.3.1

BoDonkey commented 1 year ago

Ticket created. Thanks @stepanjakl for bringing this to our attention.