decaporg / decap-cms

A Git-based CMS for Static Site Generators
https://decapcms.org
MIT License
17.96k stars 3.05k forks source link

fix(widgetsFor): return widgets for variable type lists #7296

Open domcleal opened 1 month ago

domcleal commented 1 month ago

Summary

When using a Variable Type list widget and a custom preview component, the widgetsFor helper would only return a data list with each of the items in the list, not a widgets list, e.g.

{"data" =>
    {"markdown" => "# Title"}
    {"type" => "block_body"}
}
{"widgets" => undefined} šŸš«

The widgets list should also be supplied, particularly for nested Markdown widgets, so a fully formatted preview can be rendered:

{"data" =>
    {"markdown" => "# Title"}
    {"type" => "block_body"}
}
{"widgets" =>
    {"markdown" => Object} āœ…
}

This extends support in widgetsFor to detect variable type list widgets and correctly construct the widgets return value.

Fixes #2307 (specifically https://github.com/decaporg/decap-cms/issues/2307#issuecomment-638326225 which explains it neatly).

Test plan

Using the test backend, add the following custom preview helper:

var KitchenSinkPreview = createClass({
  render: function() {
    return h('div', {},
      h('h1', {}, 'Typed list'),
      this.props.widgetsFor('typed_list').map(function(item, index) {
        return h('div', {key: index},
          h('hr', {}),
          h('strong', {}, item.getIn(['data', 'string']) || "Untitled"),

          h('dl', {},
            h('dt', {}, 'Data'),
            h('dd', {}, item.getIn(['data', 'markdown'])),

            h('dt', {}, 'Widgets'),
            h('dd', {}, item.getIn(['widgets', 'markdown'])),
          ),
        );
      })
    );
  }
});

CMS.registerPreviewTemplate("kitchenSink", KitchenSinkPreview);   

Before:

image

Only the data value is populated, so only the raw Markdown is available. The widgets return value is empty.

After:

image

In the preview pane, the Markdown widget is now able to be used to render the field.

Checklist

Please add a x inside each checkbox: