diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/QTableMetaData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/QTableMetaData.java
index 93ae4f96..1df589d1 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/QTableMetaData.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/QTableMetaData.java
@@ -54,6 +54,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLock
import com.kingsrook.qqq.backend.core.model.metadata.sharing.ShareableTableMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.QTableAutomationDetails;
import com.kingsrook.qqq.backend.core.model.metadata.tables.cache.CacheOf;
+import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
@@ -712,6 +713,25 @@ public class QTableMetaData implements QAppChildMetaData, Serializable, MetaData
+ /*******************************************************************************
+ ** Getter for sections
+ **
+ *******************************************************************************/
+ public QFieldSection getSection(String name)
+ {
+ for(QFieldSection qFieldSection : CollectionUtils.nonNullList(sections))
+ {
+ if(qFieldSection.getName().equals(name))
+ {
+ return (qFieldSection);
+ }
+ }
+
+ return (null);
+ }
+
+
+
/*******************************************************************************
** Setter for sections
**
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/SectionFactory.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/SectionFactory.java
new file mode 100644
index 00000000..52f84d78
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/SectionFactory.java
@@ -0,0 +1,221 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2025. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.backend.core.model.metadata.tables;
+
+
+import java.util.List;
+import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
+
+
+/*******************************************************************************
+ ** Factory class for creating "standard" qfield sections. e.g., if you want
+ ** the same t1, t2, and t3 section on all your tables, use this class to
+ ** produce them.
+ **
+ ** You can change the default name & iconNames for those sections, but note,
+ ** this is a static/utility style class, so those settings are static fields.
+ **
+ ** The method customT2 is provided as not much of a shortcut over "doing it yourself",
+ ** but to allow all sections for a table to be produced through calls to this factory,
+ ** so they look more similar.
+ *******************************************************************************/
+public class SectionFactory
+{
+ private static String defaultT1name = "identity";
+ private static String defaultT1iconName = "badge";
+ private static String defaultT2name = "data";
+ private static String defaultT2iconName = "text_snippet";
+ private static String defaultT3name = "dates";
+ private static String defaultT3iconName = "calendar_month";
+
+
+ /*******************************************************************************
+ ** private constructor, to enforce static usage, e.g., to make clear the fields
+ ** are static fields.
+ **
+ *******************************************************************************/
+ private SectionFactory()
+ {
+ }
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ public static QFieldSection defaultT1(String... fieldNames)
+ {
+ return new QFieldSection(defaultT1name, new QIcon().withName(defaultT1iconName), Tier.T1, List.of(fieldNames));
+ }
+
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ public static QFieldSection defaultT2(String... fieldNames)
+ {
+ return new QFieldSection(defaultT2name, new QIcon().withName(defaultT2iconName), Tier.T2, List.of(fieldNames));
+ }
+
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ public static QFieldSection customT2(String name, QIcon icon, String... fieldNames)
+ {
+ return new QFieldSection(name, icon, Tier.T2, List.of(fieldNames));
+ }
+
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ public static QFieldSection defaultT3(String... fieldNames)
+ {
+ return new QFieldSection(defaultT3name, new QIcon().withName(defaultT3iconName), Tier.T3, List.of(fieldNames));
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for defaultT1name
+ *******************************************************************************/
+ public static String getDefaultT1name()
+ {
+ return (SectionFactory.defaultT1name);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for defaultT1name
+ *******************************************************************************/
+ public static void setDefaultT1name(String defaultT1name)
+ {
+ SectionFactory.defaultT1name = defaultT1name;
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for defaultT1iconName
+ *******************************************************************************/
+ public static String getDefaultT1iconName()
+ {
+ return (SectionFactory.defaultT1iconName);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for defaultT1iconName
+ *******************************************************************************/
+ public static void setDefaultT1iconName(String defaultT1iconName)
+ {
+ SectionFactory.defaultT1iconName = defaultT1iconName;
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for defaultT2name
+ *******************************************************************************/
+ public static String getDefaultT2name()
+ {
+ return (SectionFactory.defaultT2name);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for defaultT2name
+ *******************************************************************************/
+ public static void setDefaultT2name(String defaultT2name)
+ {
+ SectionFactory.defaultT2name = defaultT2name;
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for defaultT2iconName
+ *******************************************************************************/
+ public static String getDefaultT2iconName()
+ {
+ return (SectionFactory.defaultT2iconName);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for defaultT2iconName
+ *******************************************************************************/
+ public static void setDefaultT2iconName(String defaultT2iconName)
+ {
+ SectionFactory.defaultT2iconName = defaultT2iconName;
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for defaultT3name
+ *******************************************************************************/
+ public static String getDefaultT3name()
+ {
+ return (SectionFactory.defaultT3name);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for defaultT3name
+ *******************************************************************************/
+ public static void setDefaultT3name(String defaultT3name)
+ {
+ SectionFactory.defaultT3name = defaultT3name;
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for defaultT3iconName
+ *******************************************************************************/
+ public static String getDefaultT3iconName()
+ {
+ return (SectionFactory.defaultT3iconName);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for defaultT3iconName
+ *******************************************************************************/
+ public static void setDefaultT3iconName(String defaultT3iconName)
+ {
+ SectionFactory.defaultT3iconName = defaultT3iconName;
+ }
+
+
+
+}
diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/metadata/tables/SectionFactoryTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/metadata/tables/SectionFactoryTest.java
new file mode 100644
index 00000000..5f406acb
--- /dev/null
+++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/model/metadata/tables/SectionFactoryTest.java
@@ -0,0 +1,62 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2025. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.backend.core.model.metadata.tables;
+
+
+import java.util.List;
+import com.kingsrook.qqq.backend.core.BaseTest;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+
+/*******************************************************************************
+ ** Unit test for SectionFactory
+ *******************************************************************************/
+class SectionFactoryTest extends BaseTest
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Test
+ void test()
+ {
+ QFieldSection t1section = SectionFactory.defaultT1("id", "name");
+ assertEquals(SectionFactory.getDefaultT1name(), t1section.getName());
+ assertEquals(SectionFactory.getDefaultT1iconName(), t1section.getIcon().getName());
+ assertEquals(Tier.T1, t1section.getTier());
+ assertEquals(List.of("id", "name"), t1section.getFieldNames());
+
+ QFieldSection t2section = SectionFactory.defaultT2("size", "age");
+ assertEquals(SectionFactory.getDefaultT2name(), t2section.getName());
+ assertEquals(SectionFactory.getDefaultT2iconName(), t2section.getIcon().getName());
+ assertEquals(Tier.T2, t2section.getTier());
+ assertEquals(List.of("size", "age"), t2section.getFieldNames());
+
+ QFieldSection t3section = SectionFactory.defaultT3("createDate", "modifyDate");
+ assertEquals(SectionFactory.getDefaultT3name(), t3section.getName());
+ assertEquals(SectionFactory.getDefaultT3iconName(), t3section.getIcon().getName());
+ assertEquals(Tier.T3, t3section.getTier());
+ assertEquals(List.of("createDate", "modifyDate"), t3section.getFieldNames());
+ }
+
+}
\ No newline at end of file