

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# dotcms-ui — Agent Guide23Main admin UI application for dotCMS (`/dotAdmin`). **Angular 21.2.1** with standalone components, `dot-` prefix, built and served through the Nx workspace. Agents working in this directory should read this file first, then refer to the parent guide for shared standards.45## UI Stack678| Layer | Technology | Notes |9| ----------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------- |10| Component library | **PrimeNG** | Use `p-`* components (e.g. `p-button`, `p-select`, `p-dialog`) — check the PrimeNG MCP server for API/props |11| Utility CSS | **Tailwind CSS** | Use Tailwind utilities for layout, spacing, and typography |12| Global styles | `libs/dotcms-scss/angular/styles.scss` | Imported as a global stylesheet in the build |131415**Key rules:**1617- Use Tailwind utilities (`grid`, `flex`, `gap-`*, `p-*`, etc.) for layout and spacing18- Always use PrimeNG components for interactive UI (inputs, dropdowns, dialogs, tables) rather than raw HTML equivalents19- PrimeNG icons ship via `primeicons` (`pi pi-*` class names); this package is included in the global styles2021> **Standards reference**: All Angular syntax rules, component conventions, testing patterns (Jest + Spectator), and code-placement decisions are documented in **[../../CLAUDE.md](../../CLAUDE.md)**. Do not duplicate them here.2223## Commands2425All commands must be run from the `core-web/` workspace root and prefixed with `yarn nx` (Nx is not installed globally).2627```bash28# Development29yarn nx serve dotcms-ui # Dev server at :4200, proxies /api/* → :808030yarn nx build dotcms-ui # Production build → dist/apps/dotcms-ui/31yarn nx build dotcms-ui --configuration=development # Dev build → ../../tomcat9/webapps/ROOT/dotAdmin3233# Tests34yarn nx test dotcms-ui # Run all unit tests35yarn nx test dotcms-ui --testPathPattern=my.spec # Run a specific spec file36yarn nx lint dotcms-ui # Lint37```3839## Portlets4041A **portlet** is an admin UI feature served under `/dotAdmin`, backed by a backend menu entry (`DotMenuItem`). The `dotcms-ui` app is a **shell**: it does not implement feature logic itself. It hosts portlets via Angular routing inside `MainComponentLegacyComponent`'s `<router-outlet>`.424344| Mode | Where | Route pattern |45| -------------- | ------------------------------------------------------------ | ------------------------ |46| Modern Angular | Nx lib or legacy app folder | `/tags`, `/templates`, … |47| Legacy JSP | iframe | `/c/:id` |48| Dynamic plugin | runtime registration via menu `initParams['angular-module']` | varies |495051### Where portlets live5253```mermaid54flowchart LR55 subgraph newWork [New work]56 Lib["libs/portlets/dot-feature/"]57 end58 subgraph legacy [Legacy - do not add here]59 App["apps/dotcms-ui/src/app/portlets/"]60 end61 subgraph shell [App shell only]62 Routes["app.routes.ts"]63 View["view/components/ toolbar, login"]64 Api["api/services/ guards"]65 end66 Lib --> Routes67 App --> Routes68 Routes --> View69```70717273- **New portlets** → `[libs/portlets/{feature}/](../../libs/portlets/)` as Nx libraries. Canonical reference: `[dot-tags](../../libs/portlets/dot-tags/)`.74- **Legacy portlets** → still under `[src/app/portlets/](src/app/portlets/)` (templates, content-types, form-builder, etc.). Migrate to `libs/portlets/` when touching them substantially — do not add new features here.75- **App-local code** stays in the shell: `view/components/` (toolbar, login, contentlet editor), `api/services/` (guards, app services), `shared/models/`.7677```78apps/dotcms-ui/src/app/79├── app.routes.ts # portlet registry80├── view/components/ # shell chrome (toolbar, login, editors)81├── api/services/ # guards, app-level services82└── portlets/ # legacy features only — see above83```8485### Nx lib pattern8687Each modern portlet is an Nx library that exports routes for the app shell to lazy-load:88891. Lib lives at `libs/portlets/dot-{feature}/` (complex features may split into `{feature}/portlet`, `{feature}/data-access`).902. Lib exports `dot{Feature}Routes` from `src/index.ts` / `lib.routes.ts`.913. Path alias in `[tsconfig.base.json](../../tsconfig.base.json)`: `@dotcms/portlets/dot-{feature}/portlet` (legacy app portlets use `@portlets/...`).924. Nx project name: `portlets-dot-{feature}-portlet`; tags: `type:feature`, `scope:dotcms-ui`, `portlet:{feature}`.935. For generator setup, SignalStore rules, shell/list/store/CRUD patterns, and testing — see `**[libs/portlets/CLAUDE.md](../../libs/portlets/CLAUDE.md)**` (`dot-tags` is the reference implementation).9495### Wiring into routing9697Central registry: `[src/app/app.routes.ts](src/app/app.routes.ts)`.98991. Authenticated routes mount under `MainComponentLegacyComponent`.1002. `PORTLETS_ANGULAR` lazy-loads each Angular portlet via `loadChildren`.1013. Most entries use `MenuGuardService` to enforce backend menu permissions.1024. Legacy JSP portlets use `PORTLETS_IFRAME` → `IframePortletLegacyComponent`.103104Adding a new portlet requires **both** the lib routes export **and** a new entry in `PORTLETS_ANGULAR`.105106**In the lib** (`libs/portlets/dot-tags/src/lib/lib.routes.ts`):107108```typescript109export const dotTagsRoutes: Route[] = [110 { path: '', component: DotTagsShellComponent }111];112```113114**In the app shell** (`app.routes.ts`):115116```typescript117{118 path: 'tags',119 canActivate: [MenuGuardService],120 canActivateChild: [MenuGuardService],121 loadChildren: () =>122 import('@dotcms/portlets/dot-tags/portlet').then((m) => m.dotTagsRoutes)123}124```125126### Legacy portlets (app folder)127128Portlets still under `src/app/portlets/` use NgModule-based routing (`feature-name.module.ts`, `feature-name-routing.module.ts`) and the `@portlets/...` path alias. Example: `[dot-templates](src/app/portlets/dot-templates/)`. Do not use this pattern for new work.129130## Where Code Goes131132See also the [Portlets](#portlets) section above for how features connect to routing.133134135| Scope | Location |136| ------------------------------------ | ---------------------------------------------------- |137| New portlet / feature | `libs/portlets/{feature}/` — **not** inside this app |138| UI presentational components | `libs/ui/` |139| Service to hit dotCMS rest apis | `libs/data-access/` |140| TypeScript interfaces / types | `libs/dotcms-models/` |141| App-level component (toolbar, login) | `apps/dotcms-ui/src/app/view/components/` |142| App-level service / guard | `apps/dotcms-ui/src/app/api/services/` |143144145For the full decision tree, see [../../CLAUDE.md § Code Placement Rules](../../CLAUDE.md).146147## Key Assets Bundled at Build Time148149The build copies several vendor assets into the output:150151- `node_modules/tinymce` → `/tinymce/`152- `node_modules/monaco-editor` → `assets/monaco-editor/`153- `libs/block-editor/src/lib/assets` → `assets/block-editor/`154- `libs/portlets/edit-ema/portlet/src/lib/assets` → `assets/edit-ema/`155156If these paths change (e.g. the block-editor moves), update `assets` in `project.json`.157158## Implicit Dependencies159160This app declares `"implicitDependencies": ["dotcms-webcomponents"]` in `project.json`. Changes to web components will trigger a rebuild of this app in affected-mode CI runs.
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| dotCMS/core.cursor/rules/e2e-rules.mdc · 949 | Cursor rules | setupteststylearch+5 | 89/100 | 14 days ago | |
| dotCMS/core.github/instructions/frontend.instructions.md · 949 | Copilot instructions | testlint-formatstylearch+3 | 61/100 | today | |
| dotCMS/coreCLAUDE.md · 949 | CLAUDE.md | setupbuildteststyle+7 | 99/100 | today | |
| dotCMS/corecore-web/AGENTS.md · 949 | AGENTS.md | style | 63/100 | 14 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 14 days ago | |
| dotCMS/corecore-web/apps/dotcms-ui-e2e/AGENTS.md · 949 | AGENTS.md | setupstylearchtesting-strategy+2 | 78/100 | 14 days ago | |
| dotCMS/corecore-web/apps/mcp-server/CLAUDE.md · 949 | CLAUDE.md | setupbuildtestlint-format+5 | 89/100 | 14 days ago | |
| dotCMS/corecore-web/libs/block-editor/CLAUDE.md · 949 | CLAUDE.md | archdo-not | 69/100 | 14 days ago | |
| dotCMS/corecore-web/libs/new-block-editor/CLAUDE.md · 949 | CLAUDE.md | lint-formatstyledo-notagent-behaviour | 61/100 | 14 days ago | |
| dotCMS/corecore-web/libs/portlets/CLAUDE.md · 949 | CLAUDE.md | setupteststyleui+1 | 77/100 | 14 days ago | |
| dotCMS/corecore-web/libs/portlets/edit-ema/portlet/src/lib/store/CLAUDE.md · 949 | CLAUDE.md | teststylearchtypes+2 | 65/100 | 7 days ago | |
| dotCMS/corecore-web/libs/sdk/client/CLAUDE.md · 949 | CLAUDE.md | setupbuildtestlint-format+9 | 97/100 | 14 days ago | |
| dotCMS/corecore-web/libs/sdk/react/CLAUDE.md · 949 | CLAUDE.md | setupbuildtestlint-format+9 | 97/100 | 14 days ago | |
| dotCMS/coredotCMS/src/main/java/com/dotcms/rest/CLAUDE.md · 949 | CLAUDE.md | typesdatabaseapido-not+1 | 57/100 | 14 days ago | |
| dotCMS/coretest-jmeter/CLAUDE.md · 949 | CLAUDE.md | testarchsecurityperformance+2 | 77/100 | 14 days ago | |
| dotCMS/core.cursor/rules/frontend-context.mdc · 949 | Cursor rules | teststyledocs | 78/100 | today | |
| dotCMS/core.cursor/rules/java-context.mdc · 949 | Cursor rules | buildstyle | 44/100 | 14 days ago | |
| dotCMS/core.cursor/rules/test-context.mdc · 949 | Cursor rules | testtesting-strategy | 54/100 | today | |
| dotCMS/core.github/copilot-instructions.md · 949 | Copilot instructions | setupbuildtestlint-format+11 | 84/100 | 11 days ago | |
| dotCMS/core.cursor/rules/doc-updates.mdc · 949 | Cursor rules | docs | 30/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 201k | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| aaif-goose/gooseAGENTS.md · 53k | AGENTS.md | setupbuildtestlint-format+7 | 100/100 | 8 days ago | |
| duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70 | AGENTS.md | buildteststylearch+3 | 100/100 | 14 days ago | |
| deepseek-ai/deepseek-harnessnative/landlock-run/AGENTS.md · 104k | AGENTS.md | setupteststylearch+3 | 100/100 | today | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 68k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 13 days ago | |
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | today | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 14 days ago | |
| elastic/elasticsearchx-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/AGENTS.md · 78k | AGENTS.md | buildtestlint-formatstyle+2 | 100/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/dotcms-core-core-web-apps-dotcms-ui-agents)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.