Description
Content Drive's new "New" button menu reuses the UVE palette content-type list against GET /api/v1/contenttype (DotPageContentTypeService.getAllContentTypes). Building it surfaced two gaps in the global content-type list endpoint that currently force client-side workarounds in the frontend.
Issue 1 — No way to exclude system content types
The global list returns non-creatable system content types (e.g. Favorite Page dotFavoritePage, Host) that share a base type with real content (Favorite Page is baseType CONTENT), so the type base-type filter cannot exclude them.
Frontends work around this client-side: dot-content-drive-content-type-filter strips !ct.system && ct.baseType !== FORM, and the new Content Drive picker drops Favorite Page with a -1 count adjustment. Both break/approximate pagination counts.
Ask: an optional system query param (e.g. system=false) on getContentTypes, defaulting to current behavior (backward compatible — no param ⇒ unchanged).
The SQL layer already supports a boolean system safe-condition: isBooleanField() in ContentTypeFactoryImpl includes "system", the SafeCondition machinery parameterizes it, and the count path applies the same condition (so totals stay exact). The main work is threading a dedicated param through ContentTypeResource.getContentTypes → ContentTypesPaginator.getItems → searchMultipleTypes/search + their count loops, because SearchCondition currently treats its input as EITHER a name-search term OR a condition (not both), and the picker needs name-search + system filter together.
Issue 2 — Multi-type results are not globally sorted
When multiple type filters are passed, results are grouped per base type (each group sorted by name) and paginated per group — so content types reappear on later pages (e.g. a "B…" type shows up again on page 2 after the first group's "B…" were exhausted). orderby=name should sort the entire result set across base types.
Source: the multi-type UNION path in ContentTypesPaginator.getItems / ContentTypeFactoryImpl.searchMultipleTypes and its per-type count.
Impact
Content Drive's content-type picker currently filters Favorite Page client-side (with a -1 count workaround) and shows grouped (non-global) ordering on "All Content Types". Fixing these server-side lets the frontend drop the workarounds and keeps pagination counts exact.
Acceptance Criteria
Issue 1 — system exclusion
Issue 2 — global sort across base types
General
Priority
Medium
Additional Context
Suggested files:
dotCMS/src/main/java/com/dotcms/rest/api/v1/contenttype/ContentTypeResource.java (getContentTypes, ~line 1662)
dotCMS/src/main/java/com/dotcms/util/pagination/ContentTypesPaginator.java (getItems + per-type count)
dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPIImpl.java / ContentTypeFactoryImpl.java (searchMultipleTypes, single-type search, counts)
dotCMS/src/main/java/com/dotcms/contenttype/business/sql/ContentTypeSql.java
Frontend follow-up (separate): once shipped, Content Drive can drop the client-side Favorite Page -1 workaround and rely on system=false + native global sort.
Description
Content Drive's new "New" button menu reuses the UVE palette content-type list against
GET /api/v1/contenttype(DotPageContentTypeService.getAllContentTypes). Building it surfaced two gaps in the global content-type list endpoint that currently force client-side workarounds in the frontend.Issue 1 — No way to exclude system content types
The global list returns non-creatable system content types (e.g. Favorite Page
dotFavoritePage, Host) that share a base type with real content (Favorite Page is baseTypeCONTENT), so thetypebase-type filter cannot exclude them.Frontends work around this client-side:
dot-content-drive-content-type-filterstrips!ct.system && ct.baseType !== FORM, and the new Content Drive picker drops Favorite Page with a-1count adjustment. Both break/approximate pagination counts.Ask: an optional
systemquery param (e.g.system=false) ongetContentTypes, defaulting to current behavior (backward compatible — no param ⇒ unchanged).The SQL layer already supports a boolean
systemsafe-condition:isBooleanField()inContentTypeFactoryImplincludes"system", theSafeConditionmachinery parameterizes it, and the count path applies the same condition (so totals stay exact). The main work is threading a dedicated param throughContentTypeResource.getContentTypes→ContentTypesPaginator.getItems→searchMultipleTypes/search+ their count loops, becauseSearchConditioncurrently treats its input as EITHER a name-search term OR a condition (not both), and the picker needs name-search + system filter together.Issue 2 — Multi-type results are not globally sorted
When multiple
typefilters are passed, results are grouped per base type (each group sorted by name) and paginated per group — so content types reappear on later pages (e.g. a "B…" type shows up again on page 2 after the first group's "B…" were exhausted).orderby=nameshould sort the entire result set across base types.Source: the multi-type UNION path in
ContentTypesPaginator.getItems/ContentTypeFactoryImpl.searchMultipleTypesand its per-type count.Impact
Content Drive's content-type picker currently filters Favorite Page client-side (with a
-1count workaround) and shows grouped (non-global) ordering on "All Content Types". Fixing these server-side lets the frontend drop the workarounds and keeps pagination counts exact.Acceptance Criteria
Issue 1 — system exclusion
GET /api/v1/contenttypeaccepts an optionalsystemquery param (e.g.system=false).system=false, system content types (Host, Favorite Page, etc.) are excluded from results.searchMultipleTypes) paths.-1needed).filter(name search) andsystem=falsework together in the same request.Issue 2 — global sort across base types
typefilters andorderby=name, the entire result set is sorted globally by name (not grouped per base type).General
openapi.yamlregenerated to document the newsystemparam.filter+systemcombined; multi-type global sort + stable pagination.Priority
Medium
Additional Context
Suggested files:
dotCMS/src/main/java/com/dotcms/rest/api/v1/contenttype/ContentTypeResource.java(getContentTypes, ~line 1662)dotCMS/src/main/java/com/dotcms/util/pagination/ContentTypesPaginator.java(getItems+ per-type count)dotCMS/src/main/java/com/dotcms/contenttype/business/ContentTypeAPIImpl.java/ContentTypeFactoryImpl.java(searchMultipleTypes, single-typesearch, counts)dotCMS/src/main/java/com/dotcms/contenttype/business/sql/ContentTypeSql.javaFrontend follow-up (separate): once shipped, Content Drive can drop the client-side Favorite Page
-1workaround and rely onsystem=false+ native global sort.