Merge branch 'features/dynamic-zones' of github.com:strapi/strapi into front/dz-post-data

This commit is contained in:
soupette 2019-12-09 14:06:29 +01:00
commit aa6d83669f
15 changed files with 156 additions and 27 deletions

View File

@ -72,7 +72,7 @@ Complete installation requirements can be found in the documentation under <a hr
- Ubuntu 18.04/Debian 9.x
- CentOS/RHEL 8
- Mac O/S Mojave
- macOS Mojave
- Windows 10
- Docker - [Docker-Repo](https://github.com/strapi/strapi-docker)

View File

@ -200,6 +200,7 @@ module.exports = {
'/3.0.0-beta.x/guides/external-data',
'/3.0.0-beta.x/guides/custom-data-response',
'/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/webhooks',
],

View File

@ -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 new
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.
---
## strapi install
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.
:::
---
## strapi uninstall
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.
:::
---
## strapi console
Start the server and let you eval commands into your application in real time.
```bash
strapi console
```
## strapi version
@ -300,8 +300,6 @@ Print the current globally installed Strapi version.
strapi version
```
---
## strapi help
List CLI commands.

View File

@ -493,7 +493,7 @@ sudo nano ecosystem.config.js
module.exports = {
apps : [{
name: 'your-app-name',
cwd: '/home/ubuntu/my-strapi-project/my-project'
cwd: '/home/ubuntu/my-strapi-project/my-project',
script: 'npm',
args: 'start',
env: {

View 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.
:::

View File

@ -76,7 +76,7 @@ You have to send FormData in your request body
## 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

View File

@ -134,7 +134,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
if (Object.keys(relations).length > 0) {
return model.updateRelations(
Object.assign(params, { values: relations }),
{ id: entry.id, values: relations },
{ transacting: trx }
);
}
@ -774,8 +774,8 @@ const buildSearchQuery = (qb, model, params) => {
case 'pg': {
const searchQuery = searchText.map(attribute =>
_.toLower(attribute) === attribute
? `to_tsvector(${attribute})`
: `to_tsvector("${attribute}")`
? `to_tsvector(coalesce(${attribute}, ''))`
: `to_tsvector(coalesce("${attribute}", ''))`
);
qb.orWhereRaw(`${searchQuery.join(' || ')} @@ plainto_tsquery(?)`, query);

View File

@ -1,5 +1,7 @@
'use strict';
const { get } = require('lodash');
/**
* Returns the attribute keys of the component related attributes
*/
@ -9,8 +11,10 @@ function getComponentAttributes(definition) {
);
}
const isComponent = (def, key) =>
['component', 'dynamiczone'].includes(def.attributes[key].type);
const isComponent = (def, key) => {
const type = get(def, ['attributes', key, 'type']);
return ['component', 'dynamiczone'].includes(type);
};
module.exports = {
getComponentAttributes,

View File

@ -6,11 +6,11 @@
module.exports = {
// Before saving a value.
// Fired before an `insert` or `update` query.
// Fired before an `insert`.
// beforeSave: async (model) => {},
// After saving a value.
// Fired after an `insert` or `update` query.
// Fired after an `insert`.
// afterSave: async (model, result) => {},
// Before fetching all values.

View File

@ -5,6 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Welcome to your Strapi app</title>
<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/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" />

View File

@ -5,6 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Welcome to your Strapi app</title>
<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/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" />

View File

@ -30,7 +30,7 @@
"type": "string"
},
"size": {
"type": "integer"
"type": "decimal"
},
"url": {
"type": "string",
@ -233,7 +233,7 @@
"type": "string"
},
"size": {
"type": "string"
"type": "decimal"
},
"mime": {
"type": "string"

View File

@ -32,7 +32,7 @@
"required": true
},
"size": {
"type": "string",
"type": "decimal",
"configurable": false,
"required": true
},

View File

@ -132,7 +132,7 @@ describe('Upload plugin end to end tests', () => {
id: expect.anything(),
sha256: expect.any(String),
hash: expect.any(String),
size: expect.any(String),
size: expect.any(Number),
url: expect.any(String),
provider: 'local',
name: 'rec.jpg',

View File

@ -16,13 +16,14 @@ module.exports = async (ctx, next) => {
if (isAdmin) {
ctx.state.admin = await strapi
.query('administrator', 'admin')
.findOne({ id });
.findOne({ id }, ['role']);
} else {
ctx.state.user = await strapi
.query('user', 'users-permissions')
.findOne({ id });
.findOne({ id }, ['role']);
}
} catch (err) {
strapi.log.error(err);
return handleErrors(ctx, err, 'unauthorized');
}