Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 118 additions & 1 deletion docusaurus/docs/cms/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: Command Line Interface
displayed_sidebar: cmsSidebar
description: Strapi comes with a full featured Command Line Interface (CLI) which lets you scaffold and manage your project in seconds.
sidebar_label: Strapi CLI
toc_max_heading_level: 2
tags:
- Command Line Interface (CLI)
- strapi develop
Expand Down Expand Up @@ -331,12 +332,128 @@ strapi admin:reset-user-password --email=chef@strapi.io --password=Gourmet1234

## strapi generate

Run a fully interactive CLI to generate APIs, [controllers](/cms/backend-customization/controllers), [content-types](/cms/backend-customization/models), [plugins](/cms/plugins-development/create-a-plugin), [policies](/cms/backend-customization/policies), [middlewares](/cms/backend-customization/middlewares) and [services](/cms/backend-customization/services), and [migrations](/cms/database-migrations).
Generate APIs, [controllers](/cms/backend-customization/controllers), [content-types](/cms/backend-customization/models), [policies](/cms/backend-customization/policies), [middlewares](/cms/backend-customization/middlewares), [services](/cms/backend-customization/services), and [migrations](/cms/database-migrations).

```bash
strapi generate
```

The command displays an interactive menu with the following options:

- **api** - Generate a new API with controller and service
- **controller** - Generate a new controller
- **content-type** - Generate a new content type with schema
- **policy** - Generate a new policy
- **middleware** - Generate a new middleware
- **migration** - Generate a new database migration
- **service** - Generate a new service

![strapi generate GIF](/img/assets/cli/strapi-generate.gif)

The generator detects TypeScript or JavaScript automatically and creates files with the correct extension (`.ts` or `.js`).
Generated files include commented examples. Singular and plural names must be different and use kebab-case format.

<ExpandableContent maxHeight="120px" showMoreText="Show more…" showLessText="Show less">

### API generator

Creates an API with controller and service files.

**Generated file:** `controllers/[name].js|ts`, `services/[name].js|ts`, and `routes/[name].js|ts` (standard APIs only)

### Content-type generator

Creates a content type schema with optional API files.

#### Available attribute types

| Type | Description |
|------|-------------|
| `string` | Short text |
| `text` | Long text |
| `richtext` | Rich text editor |
| `email` | Email field |
| `password` | Password field |
| `integer` | Whole number |
| `biginteger` | Large whole number |
| `float` | Decimal number |
| `decimal` | Precise decimal |
| `date` | Date only |
| `time` | Time only |
| `datetime` | Date and time |
| `timestamp` | Unix timestamp |
| `boolean` | True/false |
| `json` | JSON data |
| `enumeration` | Predefined values |
| `media` | File upload |

#### Generated files

| Condition | Generated files |
|-----------|----------------|
| Content type only | `content-types/[name]/schema.json` |
| With API bootstrap | <ul><li>`content-types/[name]/schema.json`</li><li>`controllers/[name].js\|ts`</li><li>`services/[name].js\|ts`</li><li>`routes/[name].js\|ts`</li></ul> |

### Controller generator

Creates a controller file with basic action structure.

**Generated file:** `controllers/[name].js|ts`

### Service generator

Creates a service file with basic structure.

**Generated file:** `services/[name].js|ts`

### Policy generator

Creates a policy file for access control.

**Generated file:** `policies/[name].js|ts`

### Middleware generator

Creates a middleware file for request processing.

**Generated file:** `middlewares/[name].js|ts`

### Migration generator

Creates a timestamped migration file.

**Generated file:** `database/migrations/[timestamp].[name].js|ts`

### Configuration options

<br/>

#### Destination choices

| Option | Description |
|--------|-------------|
| **New API** | Creates a new API folder |
| **Existing API** | Adds to existing API folder |
| **Existing plugin** | Adds to existing plugin folder |
| **Root** | Adds to project root (policies and middlewares only) |

#### Content type options

| Type | Description | Example |
|------|-------------|---------|
| **Collection Type** | Multiple entries | Articles, users |
| **Single Type** | Single entry | Homepage, settings |

#### Content type naming

| Field | Format | Description | Example |
|-------|--------|-------------|---------|
| **Display name** | Human-readable | Name shown in admin panel | Blog Post |
| **Singular name** | Kebab-case | Used for API endpoints | blog-post |
| **Plural name** | Kebab-case | Used for collections | blog-posts |

</ExpandableContent>

## strapi templates:generate

Create a template from the current Strapi project.
Expand Down
54 changes: 54 additions & 0 deletions docusaurus/src/components/ExpandableContent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, { useState, useRef } from 'react';

export default function ExpandableContent({
children,
showMoreText = "Show more…",
showLessText = "Show less",
maxHeight = "200px"
}) {
const [isExpanded, setIsExpanded] = useState(false);
const buttonRef = useRef(null);

const toggleExpanded = () => {
setIsExpanded(!isExpanded);

// Si on ferme le contenu, scroll vers le bouton après un petit délai
if (isExpanded) {
setTimeout(() => {
buttonRef.current?.scrollIntoView({
behavior: 'smooth',
block: 'center'
});
}, 100);
}
};

return (
<div className="expandable-content">
<div
className={`expandable-content__wrapper ${!isExpanded ? 'expandable-content__wrapper--collapsed' : ''}`}
style={{
maxHeight: isExpanded ? 'none' : maxHeight,
overflow: 'hidden',
position: 'relative'
}}
>
{children}
{!isExpanded && (
<div className="expandable-content__gradient" />
)}
</div>

<div className="expandable-content__toggle">
<button
ref={buttonRef}
className="expandable-content__button"
onClick={toggleExpanded}
type="button"
>
{isExpanded ? showLessText : showMoreText}
</button>
</div>
</div>
);
}
1 change: 1 addition & 0 deletions docusaurus/src/scss/__index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@use 'custom-doc-cards.scss';
@use 'custom-search-bar.scss';
@use 'expandable-doc-cards.scss';
@use 'expandable-content.scss';
@use 'details.scss';
@use 'diagrams.scss';
@use 'footer.scss';
Expand Down
131 changes: 131 additions & 0 deletions docusaurus/src/scss/expandable-content.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/** Component: ExpandableContent */
@use './mixins' as *;

.expandable-content {
margin-bottom: var(--strapi-spacing-6);

&__wrapper {
position: relative;
transition: max-height 0.3s ease;

&--collapsed {
position: relative;
}
}

&__gradient {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 80px;
background: linear-gradient(
to bottom,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.3) 30%,
rgba(255, 255, 255, 0.7) 60%,
rgba(255, 255, 255, 0.95) 85%,
rgba(255, 255, 255, 1) 100%
);
pointer-events: none;
}

&__toggle {
display: flex;
justify-content: center;
margin-top: var(--strapi-spacing-4);
}

&__button {
background: rgba(255, 255, 255, 0.95);
border: 1px solid var(--strapi-neutral-200);
color: var(--strapi-neutral-800);
cursor: pointer;
font-size: var(--strapi-font-size-sm);
font-weight: 500;
padding: var(--strapi-spacing-2) var(--strapi-spacing-4);
border-radius: var(--strapi-spacing-2);
transition: all 0.2s ease;
text-decoration: none;
backdrop-filter: blur(6px);
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.08),
0 1px 4px rgba(0, 0, 0, 0.06);

&:hover {
background: var(--strapi-neutral-0);
border-color: var(--strapi-neutral-300);
color: var(--strapi-neutral-900);
text-decoration: none;
transform: translateY(-1px);
box-shadow:
0 4px 12px rgba(0, 0, 0, 0.12),
0 2px 6px rgba(0, 0, 0, 0.08);
}

&:focus {
outline: none;
box-shadow:
0 0 0 2px var(--strapi-primary-200),
0 2px 8px rgba(0, 0, 0, 0.08);
}

&:focus-visible {
outline: none;
box-shadow:
0 0 0 2px var(--strapi-primary-500),
0 2px 8px rgba(0, 0, 0, 0.08);
}

&:active {
transform: translateY(0);
}
}
}

@include dark {
.expandable-content {
&__gradient {
background: linear-gradient(
to bottom,
rgba(33, 33, 52, 0) 0%,
rgba(33, 33, 52, 0.2) 20%,
rgba(33, 33, 52, 0.5) 40%,
rgba(33, 33, 52, 0.8) 65%,
rgba(33, 33, 52, 0.95) 85%,
rgba(33, 33, 52, 1) 100%
);
}

&__button {
background: rgba(33, 33, 52, 0.95);
border-color: var(--strapi-neutral-200);
color: var(--strapi-neutral-800);
backdrop-filter: blur(8px);
box-shadow:
0 2px 12px rgba(0, 0, 0, 0.3),
0 1px 6px rgba(0, 0, 0, 0.2);

&:hover {
background: var(--strapi-neutral-0);
border-color: var(--strapi-neutral-300);
color: var(--strapi-neutral-900);
box-shadow:
0 4px 20px rgba(0, 0, 0, 0.4),
0 2px 10px rgba(0, 0, 0, 0.25);
}

&:focus {
box-shadow:
0 0 0 2px var(--strapi-primary-600),
0 2px 12px rgba(0, 0, 0, 0.3);
}

&:focus-visible {
box-shadow:
0 0 0 2px var(--strapi-primary-600),
0 2px 12px rgba(0, 0, 0, 0.3);
}
}
}
}
2 changes: 2 additions & 0 deletions docusaurus/src/theme/MDXComponents.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import FeedbackPlaceholder from '../components/FeedbackPlaceholder';
import CustomDocCard from '../components/CustomDocCard';
import CustomDocCardsWrapper from '../components/CustomDocCardsWrapper';
import ExpandableDocCardsWrapper from '../components/ExpandableDocCardsWrapper';
import ExpandableContent from '../components/ExpandableContent.js';
import { InteractiveQueryBuilder } from '../components/InteractiveQueryBuilder/InteractiveQueryBuilder';
import { AlphaBadge, BetaBadge, FeatureFlagBadge, EnterpriseBadge, GrowthBadge, SsoBadge, CloudEssentialBadge, CloudProBadge, CloudScaleBadge, NewBadge, UpdatedBadge, VersionBadge } from '../components/Badge';
import { SideBySideColumn, SideBySideContainer } from '../components';
Expand Down Expand Up @@ -72,6 +73,7 @@ export default {
CustomDocCard,
CustomDocCardsWrapper,
ExpandableDocCardsWrapper,
ExpandableContent,
InteractiveQueryBuilder,
SubtleCallout,
ThemedImage,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.