@se-studio/skills 1.9.15 → 1.9.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/references/contentful-cms-cms-guidelines/html-component-authoring.md +25 -2
- package/skills/se-marketing-sites-cms-routes-and-appshared/SKILL.md +7 -3
- package/skills/se-marketing-sites-create-component/SKILL.md +10 -2
- package/skills/se-marketing-sites-customer-simplicity/SKILL.md +1 -1
- package/skills/se-marketing-sites-lib-cms-structure/SKILL.md +2 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @se-studio/skills
|
|
2
2
|
|
|
3
|
+
## 1.9.17
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d645ee4: Document both person URL shapes. The legacy generator uses `/peopleType/[peopleType]/[person]`. The section generator uses a static `/{peopleSlug}/{type}/[person]`.
|
|
8
|
+
|
|
9
|
+
## 1.9.16
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 049abbb: Document how to place a designed HTML page: site chrome stays in the template, editor-owned or repeated sections become registered components, and HtmlComponent is only for a developer-owned island. Specimens drop embedded fonts, a second colour palette, raw forms, and hand-rolled analytics.
|
|
14
|
+
|
|
3
15
|
## 1.9.15
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -9,9 +9,32 @@ metadata:
|
|
|
9
9
|
|
|
10
10
|
# HtmlComponent Authoring Guide
|
|
11
11
|
|
|
12
|
-
`HtmlComponent` is a CMS content type that renders developer-authored HTML directly into the page. It bypasses the standard component registration system
|
|
12
|
+
`HtmlComponent` is a CMS content type that renders developer-authored HTML directly into the page. It bypasses the standard component registration system.
|
|
13
13
|
|
|
14
|
-
**
|
|
14
|
+
Author it only after the recorded call is **keep**. That call is in `packages/contentful-cms/docs/editor-tasks/create-html-component.md`. A layout the library cannot produce does not keep the section. A registered type that could render it does not promote the section. Do not use HtmlComponent + `customCss` to reconstruct a Webflow page. See `se-marketing-sites-customer-simplicity` and PHILOSOPHY §5a.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## From a designed page file
|
|
19
|
+
|
|
20
|
+
A self-contained HTML file (nav, page, footer, embedded font) is a specimen. Do not paste it into `rawHtml`. The shelf decision is in `packages/contentful-cms/docs/editor-tasks/create-html-component.md` (`cms-edit://customer/task-create-html-component`):
|
|
21
|
+
|
|
22
|
+
| Shelf | When |
|
|
23
|
+
|-----|------|
|
|
24
|
+
| Site layout | Nav, footer, menu, contact panel. Leave them in the file. |
|
|
25
|
+
| Registered component | An editor will change the words, media, or links, or the section repeats (on this page or another). Build or reuse a component. Do not author it here. |
|
|
26
|
+
| `HtmlComponent` | The recorded call is **keep**: a developer will own it, editors will not change the words, media, or links, and it does not repeat. A layout match does not decide this. A first version gets the same keep-or-promote call. Continue below only after **keep**. |
|
|
27
|
+
|
|
28
|
+
When the shelf is `HtmlComponent`:
|
|
29
|
+
|
|
30
|
+
- Drop `@font-face` and embedded font files. The site already loads the brand font.
|
|
31
|
+
- Drop a second `:root` palette. Use the named colour and type classes in the project style guide. Motion that those classes cannot express goes in `customCss`, using the site’s existing tokens.
|
|
32
|
+
- Do not paste a `<form>`. Forms use the site’s registered form.
|
|
33
|
+
- Do not push to `dataLayer` from `customJs`. `HtmlComponent` does not emit analytics. Clicks that must be measured are registered links.
|
|
34
|
+
- One page has one `h1`. Set `isHero` only when this block is that heading.
|
|
35
|
+
- Fill `markdownContent` with the visible sentences.
|
|
36
|
+
|
|
37
|
+
Regenerate `html-component-style-guide.md` only when that site’s tokens have changed.
|
|
15
38
|
|
|
16
39
|
---
|
|
17
40
|
|
|
@@ -31,10 +31,14 @@ export default function CmsRoutesLayout({ children }: { children: React.ReactNod
|
|
|
31
31
|
| `/{slug1}/{slug2}/...` | `[level1]/[...slugs]/page.ts` | Multi-level pages |
|
|
32
32
|
| `/articles/` | `articles/page.ts` | Articles index (uses ARTICLES_BASE) |
|
|
33
33
|
| `/articles/{type}/` | `articles/[articleType]/page.ts` | Article type index |
|
|
34
|
-
| `/articles/{type}/{tag}/` | `articles/[articleType]/[tag]/page.ts` | Article type + tag index.
|
|
34
|
+
| `/articles/{type}/{tag}/` | `articles/[articleType]/[tag]/page.ts` | Article type + tag index. Generated when that base sets `tagInPath: true`. |
|
|
35
35
|
| `/articles/{type}/{tag}/{article}/` | `articles/[articleType]/[tag]/[...slugs]/page.ts` | Individual article with a tag segment. Same `tagInPath` rule. |
|
|
36
36
|
| `/tags/`, `/tags/{tag}/` | `tags/` | Tag index when `tags: true` |
|
|
37
|
-
| `/people
|
|
37
|
+
| `/people/` | `people/page.ts` | People index when `personBases[].index` is on |
|
|
38
|
+
| `/people/{person}/` | `people/[person]/page.ts` | Legacy person with no person type. No redirect to the typed URL |
|
|
39
|
+
| `/peopleType/{peopleType}/{person}/` | `peopleType/[peopleType]/[person]/page.ts` | Legacy person with a person type. The type segment is dynamic so it does not sit beside `people/[person]` |
|
|
40
|
+
| `/{peopleSlug}/{type}/`, `/{peopleSlug}/{type}/{person}/` | `{peopleSlug}/{type}/page.ts`, `{peopleSlug}/{type}/[person]/page.ts` | Section generator. The type segment is the person type slug, not `[peopleType]`. With no person prefix the folders are `/{type}/` and `/{type}/[person]/` |
|
|
41
|
+
| `/people/{type}/`, `/people/{type}/{person}/` | `people/{type}/` | Extra folders for each name in `personBases[].types` |
|
|
38
42
|
|
|
39
43
|
Base paths come from `@/lib/constants` (e.g. ARTICLES_BASE = `/learning-hub` or `/articles`).
|
|
40
44
|
|
|
@@ -99,7 +103,7 @@ export default async function (props: PageProps<'/[level1]'>) {
|
|
|
99
103
|
}
|
|
100
104
|
```
|
|
101
105
|
|
|
102
|
-
A dynamic `articles` route uses `converterContext.urlCalculators` (`article`, `articleType`, `articleTypeTag`). Import `converterContext` from `@/lib/converter-context` when that module exists (so route files don't pull in cms-server); otherwise from `@/lib/cms-server`. A fixed article folder, and a dynamic base whose path is not `articles`, passes the path of
|
|
106
|
+
A dynamic `articles` route uses `converterContext.urlCalculators` (`article`, `articleType`, `articleTypeTag`). Import `converterContext` from `@/lib/converter-context` when that module exists (so route files don't pull in cms-server); otherwise from `@/lib/cms-server`. A fixed article folder, and a dynamic base whose path is not `articles`, passes the path of the file that was written (`/work/`, `/work/${articleSlug}/`). `article()` prefixes `ARTICLES_BASE` and, when primary tags are on, inserts `other`. That is a different URL from the file that was written. The generator writes `[tag]` pages with `articleTypeTag` when `tagInPath` is true. Feature flags live in `marketing-routes.json` and `src/generated/marketing-flags.ts`. The legacy generator writes a typed person at `/peopleType/${peopleType}/${slug}/`. The section generator writes a static `/${peopleSlug}/${type}/${slug}/`, or `/${type}/${slug}/` when there is no person prefix. A person with no type is `/${peopleSlug}/${slug}/`. Neither route redirects to the other. `[level1]` stays a generic page.
|
|
103
107
|
|
|
104
108
|
## See Also
|
|
105
109
|
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: se-marketing-sites-create-component
|
|
3
|
-
description: "Guide for creating new CMS-driven components in the SE Core Product monorepo. Use this skill when asked to create a new component,
|
|
3
|
+
description: "Guide for creating new CMS-driven components in the SE Core Product monorepo. Use this skill when asked to create a new component, or when a designed HTML page needs a registered section. Ensures adherence to the 4-layer architecture."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Creating CMS Components
|
|
7
7
|
|
|
8
8
|
This guide explains how to build new CMS-driven components following the established architecture patterns in this codebase.
|
|
9
9
|
|
|
10
|
+
## When the brief is a designed HTML page
|
|
11
|
+
|
|
12
|
+
Read `packages/contentful-cms/docs/editor-tasks/create-html-component.md` and record **keep** or **promote** for each section before writing code. A first version with no designed file gets the same call. Do not start the four layers until the call is **promote**. Do not open the HTML playbook until the call is **keep**.
|
|
13
|
+
|
|
14
|
+
**Promote** is required when an editor will change the words, media, or links, or the section repeats (on this page or another). Then follow the four layers below. Do not paste the HTML document in as the component. Leave nav, footer, menu, and the contact panel to the page template.
|
|
15
|
+
|
|
16
|
+
**Keep** is allowed only when a developer will own it, an editor will not change the words, media, or links, and it does not repeat. Motion, a tool demo, or vendor JS can be that island. A layout match does not promote it, and a new layout does not keep it. The keep path is the playbook above, including the project HTML style guide.
|
|
17
|
+
|
|
10
18
|
## Architecture Overview
|
|
11
19
|
|
|
12
20
|
All components follow a **four-layer architecture** and must remain **Server Components** by default.
|
|
@@ -254,4 +262,4 @@ export const MyNewRegistration = defineComponent({
|
|
|
254
262
|
* Do **not** flatten body/`additionalCopy` for layout; use `<RtfOrString>`.
|
|
255
263
|
* Do **not** invent or filter CMS `links` into roles unless Nick asks.
|
|
256
264
|
* Prefer Tailwind tokens over new `globals.css` layout rules; CSS islands are debt.
|
|
257
|
-
* Empty field → omit UI (**fail closed**). Load `se-marketing-sites-customer-simplicity` on remake tasks.
|
|
265
|
+
* Empty field → omit UI (**fail closed**). Load `se-marketing-sites-customer-simplicity` on remake tasks. Its HtmlComponent escape hatch does not move a section onto or off HtmlComponent after **keep** or **promote** is recorded.
|
|
@@ -34,7 +34,7 @@ Canonical: `docs/PHILOSOPHY.md` §5a. Review: `customer-code-review.md`. Session
|
|
|
34
34
|
## Escape hatches (narrow)
|
|
35
35
|
|
|
36
36
|
- `globals.css`: shared primitives only (keyframes, RTF element maps, true design-system utilities) — **not** per-page layout ports
|
|
37
|
-
- HtmlComponent + `customCss`:
|
|
37
|
+
- HtmlComponent + `customCss`: only when the recorded call is **keep** (`create-html-component.md`). A layout a registered type cannot express does not make that call. Do not move a section onto or off HtmlComponent after **keep** or **promote** is recorded. **Not** the default Webflow remake path.
|
|
38
38
|
|
|
39
39
|
## Related
|
|
40
40
|
|
|
@@ -41,12 +41,10 @@ export const customerName = '...';
|
|
|
41
41
|
export const applicationName = '...';
|
|
42
42
|
export const siteTitle = '...';
|
|
43
43
|
export const siteDescription = '...';
|
|
44
|
-
export const enablePerson = false;
|
|
45
|
-
export const enablePeopleIndex = false;
|
|
46
|
-
export const enableTag = false;
|
|
47
|
-
export const enableTagsIndex = false;
|
|
48
44
|
```
|
|
49
45
|
|
|
46
|
+
`enablePerson`, `enablePeopleIndex`, `enableTag`, `enableTagsIndex`, `enableArticleTypeIndex`, `enableArticleTypeTagIndex`, and `enablePrimaryTagPartOfSlug` live in `src/lib/marketing-routes.json`. `scripts/generate-marketing-routes.mjs` writes `src/generated/marketing-flags.ts`.
|
|
47
|
+
|
|
50
48
|
## Data Flow
|
|
51
49
|
|
|
52
50
|
```
|