mirror of
https://github.com/strapi/strapi.git
synced 2025-08-09 09:14:49 +00:00
Merge branch 'features/dynamic-zones' of github.com:strapi/strapi into front/dz-post-data
This commit is contained in:
commit
aa6d83669f
@ -72,7 +72,7 @@ Complete installation requirements can be found in the documentation under <a hr
|
|||||||
|
|
||||||
- Ubuntu 18.04/Debian 9.x
|
- Ubuntu 18.04/Debian 9.x
|
||||||
- CentOS/RHEL 8
|
- CentOS/RHEL 8
|
||||||
- Mac O/S Mojave
|
- macOS Mojave
|
||||||
- Windows 10
|
- Windows 10
|
||||||
- Docker - [Docker-Repo](https://github.com/strapi/strapi-docker)
|
- Docker - [Docker-Repo](https://github.com/strapi/strapi-docker)
|
||||||
|
|
||||||
|
@ -200,6 +200,7 @@ module.exports = {
|
|||||||
'/3.0.0-beta.x/guides/external-data',
|
'/3.0.0-beta.x/guides/external-data',
|
||||||
'/3.0.0-beta.x/guides/custom-data-response',
|
'/3.0.0-beta.x/guides/custom-data-response',
|
||||||
'/3.0.0-beta.x/guides/custom-admin',
|
'/3.0.0-beta.x/guides/custom-admin',
|
||||||
|
'/3.0.0-beta.x/guides/draft',
|
||||||
'/3.0.0-beta.x/guides/slug',
|
'/3.0.0-beta.x/guides/slug',
|
||||||
'/3.0.0-beta.x/guides/webhooks',
|
'/3.0.0-beta.x/guides/webhooks',
|
||||||
],
|
],
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
Strapi comes with a full featured Command Line Interface (CLI) which lets you scaffold and manage your project in seconds.
|
Strapi comes with a full featured Command Line Interface (CLI) which lets you scaffold and manage your project in seconds.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## strapi new
|
## strapi new
|
||||||
|
|
||||||
Create a new project.
|
Create a new project.
|
||||||
@ -245,8 +243,6 @@ strapi generate:plugin <name>
|
|||||||
|
|
||||||
Please refer to the [local plugins](../plugin-development/quick-start.md) section to know more.
|
Please refer to the [local plugins](../plugin-development/quick-start.md) section to know more.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## strapi install
|
## strapi install
|
||||||
|
|
||||||
Install a plugin in the project.
|
Install a plugin in the project.
|
||||||
@ -264,8 +260,6 @@ strapi install <name>
|
|||||||
Some plugins have admin panel integrations, your admin panel might have to be rebuilt. This can take some time.
|
Some plugins have admin panel integrations, your admin panel might have to be rebuilt. This can take some time.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## strapi uninstall
|
## strapi uninstall
|
||||||
|
|
||||||
Uninstall a plugin from the project.
|
Uninstall a plugin from the project.
|
||||||
@ -290,7 +284,13 @@ options [--delete-files]
|
|||||||
Some plugins have admin panel integrations, your admin panel might have to be rebuilt. This can take some time.
|
Some plugins have admin panel integrations, your admin panel might have to be rebuilt. This can take some time.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
---
|
## strapi console
|
||||||
|
|
||||||
|
Start the server and let you eval commands into your application in real time.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
strapi console
|
||||||
|
```
|
||||||
|
|
||||||
## strapi version
|
## strapi version
|
||||||
|
|
||||||
@ -300,8 +300,6 @@ Print the current globally installed Strapi version.
|
|||||||
strapi version
|
strapi version
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## strapi help
|
## strapi help
|
||||||
|
|
||||||
List CLI commands.
|
List CLI commands.
|
||||||
|
@ -493,7 +493,7 @@ sudo nano ecosystem.config.js
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
apps : [{
|
apps : [{
|
||||||
name: 'your-app-name',
|
name: 'your-app-name',
|
||||||
cwd: '/home/ubuntu/my-strapi-project/my-project'
|
cwd: '/home/ubuntu/my-strapi-project/my-project',
|
||||||
script: 'npm',
|
script: 'npm',
|
||||||
args: 'start',
|
args: 'start',
|
||||||
env: {
|
env: {
|
||||||
|
123
docs/3.0.0-beta.x/guides/draft.md
Normal file
123
docs/3.0.0-beta.x/guides/draft.md
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
# Draft system
|
||||||
|
|
||||||
|
This guide will explain how to create draft system. That will you manage draft, published, archive status.
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
What we want here is to fetch only data that have a `published` status.
|
||||||
|
|
||||||
|
But we don't want to use [parameters](../content-api/parameters.md) (eg. /articles?status=published) because you can easily fake the params.
|
||||||
|
|
||||||
|
To be able to do that, you have first to understand some concepts.
|
||||||
|
|
||||||
|
When you create a content type, it generates an API with the following list of [endpoints](../content-api/endpoint.md).
|
||||||
|
|
||||||
|
Each of these endpoint triggers a controller action. Here is the list of [controller actions](../concepts/controller.md) that exist by default when a content type is created.
|
||||||
|
|
||||||
|
If you check the controller file of your generated API `./api/{content-type}/controller/{Content-Type}.js`, you will see an empty file. It is because all the default logic is managed by Strapi. But you can override these actions with your own code.
|
||||||
|
|
||||||
|
And that is what we will do to filter to `published` status by default.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
In our example we will use an Article content type. By default when you fetch articles, you will got all articles.
|
||||||
|
Let's consider you don't want to expose articles that are in `draft` or `archive` status.
|
||||||
|
|
||||||
|
To enforce this rule we will customize the action that fetchs all articles to just fetch `published` articles.
|
||||||
|
|
||||||
|
To follow the example your will have to create a content type `articles` and add the following field definition:
|
||||||
|
|
||||||
|
- `string` attribute named `title`
|
||||||
|
- `text` attribute named `content`
|
||||||
|
- `enumeration` attribute named `status` with `draft`, `published`, `archive`
|
||||||
|
|
||||||
|
Then add some data with different `status`.
|
||||||
|
|
||||||
|
## Override controller action
|
||||||
|
|
||||||
|
To customize the function that fetch all our articles we will have to override the `find` function.
|
||||||
|
|
||||||
|
First, to see the difference, let's request `GET /articles`. You will see all the data you created.
|
||||||
|
Now let's start the customization.
|
||||||
|
|
||||||
|
**Path —** `./api/article/controller/Article.js`
|
||||||
|
|
||||||
|
```js
|
||||||
|
module.exports = {
|
||||||
|
async find() {
|
||||||
|
return 'strapi';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
After saving the new function, let's restart the `GET /articles` request. We will see `strapi` as response.
|
||||||
|
|
||||||
|
## Get the data back
|
||||||
|
|
||||||
|
We now know the function we have to update, but we just want to customize the returned article values.
|
||||||
|
|
||||||
|
In the [controller documentation](../concepts/controllers.html#extending-a-model-controller) you will find the default implementation of every actions. It will help you overwrite the fetch logic.
|
||||||
|
|
||||||
|
**Path —** `./api/article/controller/Article.js`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { sanitizeEntity } = require('strapi-utils');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async find(ctx) {
|
||||||
|
let entities;
|
||||||
|
if (ctx.query._q) {
|
||||||
|
entities = await strapi.services.article.search(ctx.query);
|
||||||
|
} else {
|
||||||
|
entities = await strapi.services.article.find(ctx.query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entities.map(entity =>
|
||||||
|
sanitizeEntity(entity, { model: strapi.models.article })
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
And now the data is back on `GET /articles`
|
||||||
|
|
||||||
|
## Apply our changes
|
||||||
|
|
||||||
|
Here we want force to fetch articles that have status equal to `published`.
|
||||||
|
|
||||||
|
The way to do that is to set `ctx.query.status` to `published`.
|
||||||
|
It will force the filter of the query.
|
||||||
|
|
||||||
|
**Path —** `./api/restaurant/controller/Restaurant.js`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { sanitizeEntity } = require('strapi-utils');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async find(ctx) {
|
||||||
|
let entities;
|
||||||
|
|
||||||
|
ctx.query = {
|
||||||
|
...ctx.query,
|
||||||
|
status: 'published
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ctx.query._q) {
|
||||||
|
entities = await strapi.services.article.search(ctx.query);
|
||||||
|
} else {
|
||||||
|
entities = await strapi.services.article.find(ctx.query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entities.map(entity =>
|
||||||
|
sanitizeEntity(entity, { model: strapi.models.article })
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
And tada! Draft and archived articles disapeared.
|
||||||
|
|
||||||
|
::: tip
|
||||||
|
This guide can be applied to any other controller action.
|
||||||
|
:::
|
||||||
|
|
@ -76,7 +76,7 @@ You have to send FormData in your request body
|
|||||||
|
|
||||||
## Upload files related to an entry
|
## Upload files related to an entry
|
||||||
|
|
||||||
To upload files that will be liked to an specific entry.
|
To upload files that will be linked to an specific entry.
|
||||||
|
|
||||||
### Request parameters
|
### Request parameters
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
|||||||
|
|
||||||
if (Object.keys(relations).length > 0) {
|
if (Object.keys(relations).length > 0) {
|
||||||
return model.updateRelations(
|
return model.updateRelations(
|
||||||
Object.assign(params, { values: relations }),
|
{ id: entry.id, values: relations },
|
||||||
{ transacting: trx }
|
{ transacting: trx }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -774,8 +774,8 @@ const buildSearchQuery = (qb, model, params) => {
|
|||||||
case 'pg': {
|
case 'pg': {
|
||||||
const searchQuery = searchText.map(attribute =>
|
const searchQuery = searchText.map(attribute =>
|
||||||
_.toLower(attribute) === attribute
|
_.toLower(attribute) === attribute
|
||||||
? `to_tsvector(${attribute})`
|
? `to_tsvector(coalesce(${attribute}, ''))`
|
||||||
: `to_tsvector("${attribute}")`
|
: `to_tsvector(coalesce("${attribute}", ''))`
|
||||||
);
|
);
|
||||||
|
|
||||||
qb.orWhereRaw(`${searchQuery.join(' || ')} @@ plainto_tsquery(?)`, query);
|
qb.orWhereRaw(`${searchQuery.join(' || ')} @@ plainto_tsquery(?)`, query);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const { get } = require('lodash');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the attribute keys of the component related attributes
|
* Returns the attribute keys of the component related attributes
|
||||||
*/
|
*/
|
||||||
@ -9,8 +11,10 @@ function getComponentAttributes(definition) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isComponent = (def, key) =>
|
const isComponent = (def, key) => {
|
||||||
['component', 'dynamiczone'].includes(def.attributes[key].type);
|
const type = get(def, ['attributes', key, 'type']);
|
||||||
|
return ['component', 'dynamiczone'].includes(type);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getComponentAttributes,
|
getComponentAttributes,
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// Before saving a value.
|
// Before saving a value.
|
||||||
// Fired before an `insert` or `update` query.
|
// Fired before an `insert`.
|
||||||
// beforeSave: async (model) => {},
|
// beforeSave: async (model) => {},
|
||||||
|
|
||||||
// After saving a value.
|
// After saving a value.
|
||||||
// Fired after an `insert` or `update` query.
|
// Fired after an `insert`.
|
||||||
// afterSave: async (model, result) => {},
|
// afterSave: async (model, result) => {},
|
||||||
|
|
||||||
// Before fetching all values.
|
// Before fetching all values.
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
<title>Welcome to your Strapi app</title>
|
<title>Welcome to your Strapi app</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="robots" content="noindex">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet" />
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet" />
|
||||||
<link href="https://fonts.googleapis.com/css?family=Lato:400,700&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css?family=Lato:400,700&display=swap" rel="stylesheet" />
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
<title>Welcome to your Strapi app</title>
|
<title>Welcome to your Strapi app</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="robots" content="noindex">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet" />
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet" />
|
||||||
<link href="https://fonts.googleapis.com/css?family=Lato:400,700&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css?family=Lato:400,700&display=swap" rel="stylesheet" />
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"type": "integer"
|
"type": "decimal"
|
||||||
},
|
},
|
||||||
"url": {
|
"url": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -233,7 +233,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"type": "string"
|
"type": "decimal"
|
||||||
},
|
},
|
||||||
"mime": {
|
"mime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -260,4 +260,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"type": "string",
|
"type": "decimal",
|
||||||
"configurable": false,
|
"configurable": false,
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
@ -56,4 +56,4 @@
|
|||||||
"configurable": false
|
"configurable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ describe('Upload plugin end to end tests', () => {
|
|||||||
id: expect.anything(),
|
id: expect.anything(),
|
||||||
sha256: expect.any(String),
|
sha256: expect.any(String),
|
||||||
hash: expect.any(String),
|
hash: expect.any(String),
|
||||||
size: expect.any(String),
|
size: expect.any(Number),
|
||||||
url: expect.any(String),
|
url: expect.any(String),
|
||||||
provider: 'local',
|
provider: 'local',
|
||||||
name: 'rec.jpg',
|
name: 'rec.jpg',
|
||||||
|
@ -16,13 +16,14 @@ module.exports = async (ctx, next) => {
|
|||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
ctx.state.admin = await strapi
|
ctx.state.admin = await strapi
|
||||||
.query('administrator', 'admin')
|
.query('administrator', 'admin')
|
||||||
.findOne({ id });
|
.findOne({ id }, ['role']);
|
||||||
} else {
|
} else {
|
||||||
ctx.state.user = await strapi
|
ctx.state.user = await strapi
|
||||||
.query('user', 'users-permissions')
|
.query('user', 'users-permissions')
|
||||||
.findOne({ id });
|
.findOne({ id }, ['role']);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
strapi.log.error(err);
|
||||||
return handleErrors(ctx, err, 'unauthorized');
|
return handleErrors(ctx, err, 'unauthorized');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user