diff --git a/src/Umbraco.Deploy.Contrib/DataTypeConfigurationConnectors/DocTypeGridEditorDataTypeConfigurationConnector.cs b/src/Umbraco.Deploy.Contrib/DataTypeConfigurationConnectors/DocTypeGridEditorDataTypeConfigurationConnector.cs
new file mode 100644
index 0000000..e55cddf
--- /dev/null
+++ b/src/Umbraco.Deploy.Contrib/DataTypeConfigurationConnectors/DocTypeGridEditorDataTypeConfigurationConnector.cs
@@ -0,0 +1,180 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Umbraco.Core;
+using Umbraco.Core.Configuration.Grid;
+using Umbraco.Core.Deploy;
+using Umbraco.Core.Models;
+using Umbraco.Core.Services;
+using Umbraco.Deploy.Connectors.DataTypeConfigurationConnectors;
+using Umbraco.Deploy.Core;
+using Umbraco.Web.PropertyEditors;
+
+namespace Umbraco.Deploy.Contrib.DataTypeConfigurationConnectors
+{
+ ///
+ /// Implements a Grid layout data type configuration connector supporting DocTypeGridEditor.
+ ///
+ public class DocTypeGridEditorDataTypeConfigurationConnector : DataTypeConfigurationConnectorBase2
+ {
+ private readonly IGridConfig _gridConfig;
+ private readonly IContentTypeService _contentTypeService;
+
+ ///
+ public override IEnumerable PropertyEditorAliases { get; } = new[]
+ {
+ Constants.PropertyEditors.Aliases.Grid
+ };
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The grid configuration.
+ /// The content type service.
+ public DocTypeGridEditorDataTypeConfigurationConnector(IGridConfig gridConfig, IContentTypeService contentTypeService)
+ {
+ _gridConfig = gridConfig;
+ _contentTypeService = contentTypeService;
+ }
+
+ ///
+ public override string ToArtifact(IDataType dataType, ICollection dependencies, IContextCache contextCache)
+ {
+ if (dataType.ConfigurationAs() is GridConfiguration gridConfiguration &&
+ gridConfiguration.Items?.ToObject() is GridConfigurationItems gridConfigurationItems)
+ {
+ // Get all element types (when needed)
+ var allElementTypes = new Lazy>(() => _contentTypeService.GetAll().Where(x => x.IsElement).ToList());
+
+ // Process DTGE editors
+ foreach (var gridEditor in GetGridEditors(gridConfigurationItems).Where(IsDocTypeGridEditor))
+ {
+ if (gridEditor.Config.TryGetValue("allowedDocTypes", out var allowedDocTypesConfig) &&
+ allowedDocTypesConfig is JArray allowedDocTypes &&
+ allowedDocTypes.Count > 0)
+ {
+ string[] docTypes = allowedDocTypes.Values().WhereNotNull().ToArray();
+
+ // Use regex matching
+ AddDependencies(dependencies, allElementTypes.Value.Where(x => docTypes.Any(y => Regex.IsMatch(x.Alias, y))));
+ }
+ else
+ {
+ // Add all element types as dependencies and stop processing
+ AddDependencies(dependencies, allElementTypes.Value);
+ break;
+ }
+ }
+ }
+
+ return base.ToArtifact(dataType, dependencies, contextCache);
+ }
+
+ private static void AddDependencies(ICollection dependencies, IEnumerable contentTypes)
+ {
+ foreach (var contentType in contentTypes)
+ {
+ dependencies.Add(new ArtifactDependency(contentType.GetUdi(), true, ArtifactDependencyMode.Exist));
+ }
+ }
+
+ ///
+ /// Gets the grid editors used within the grid configuration.
+ ///
+ /// The grid configuration items.
+ ///
+ /// The used grid editors (returns all editors if any of the areas allows all editors).
+ ///
+ protected virtual IEnumerable GetGridEditors(GridConfigurationItems gridConfigurationItems)
+ {
+ foreach (var gridEditor in _gridConfig.EditorsConfig.Editors)
+ {
+ if (IsAllowedGridEditor(gridConfigurationItems, gridEditor.Alias))
+ {
+ yield return gridEditor;
+ }
+ }
+ }
+
+ ///
+ /// Determines whether the grid editor alias is allowed in the specified grid configuration.
+ ///
+ /// The grid configuration items.
+ /// The alias.
+ ///
+ /// true if the grid editor alias is allowed in the specified grid configuration; otherwise, false.
+ ///
+ protected static bool IsAllowedGridEditor(GridConfigurationItems gridConfigurationItems, string alias)
+ => gridConfigurationItems.Layouts.Any(x => x.Areas.Any(y => y.AllowAll || y.Allowed.Contains(alias)));
+
+ ///
+ /// Determines whether the grid editor is the DTGE.
+ ///
+ /// The grid editor.
+ ///
+ /// true if the grid editor is the DTGE; otherwise, false.
+ ///
+ protected static bool IsDocTypeGridEditor(IGridEditorConfig gridEditor)
+ => !string.IsNullOrEmpty(gridEditor.View) && gridEditor.View.Contains("doctypegrideditor");
+
+ ///
+ /// The grid configuration items.
+ ///
+ protected sealed class GridConfigurationItems
+ {
+ ///
+ /// Gets or sets the row configurations.
+ ///
+ ///
+ /// The row configurations.
+ ///
+ [JsonProperty("layouts")]
+ public GridConfigurationLayout[] Layouts { get; set; } = Array.Empty();
+ }
+
+ ///
+ /// The grid row configuration.
+ ///
+ protected sealed class GridConfigurationLayout
+ {
+ ///
+ /// Gets or sets the areas.
+ ///
+ ///
+ /// The areas.
+ ///
+ [JsonProperty("areas")]
+ public GridConfigurationLayoutArea[] Areas { get; set; } = Array.Empty();
+ }
+
+ ///
+ /// The grid row configuration area.
+ ///
+ protected sealed class GridConfigurationLayoutArea
+ {
+ ///
+ /// Gets or sets a value indicating whether all grid editors are allowed.
+ ///
+ ///
+ /// true if all grid editors are allowed; otherwise, false.
+ ///
+ ///
+ /// Defaults to true.
+ ///
+ [JsonProperty("allowAll")]
+ public bool AllowAll { get; set; } = true;
+
+ ///
+ /// Gets or sets the allowed grid editor aliases.
+ ///
+ ///
+ /// The allowed grid editor aliases.
+ ///
+ [JsonProperty("allowed")]
+ public string[] Allowed { get; set; } = Array.Empty();
+ }
+ }
+}