mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 23:57:32 +00:00
Merge branch 'master' into patch-2
This commit is contained in:
commit
8b6372c9dc
@ -92,7 +92,7 @@ The controllers are defined in each `./api/**/controllers/` folders. Every JavaS
|
||||
|
||||
## Filters
|
||||
|
||||
Filters are a handy way to request data according to generic parameters. It makes filtering, sorting and paginating easy and reusable (eg. `GET /user?_limit=30&name=John`).
|
||||
Filters are a handy way to request data according to generic parameters. It makes filtering, sorting and paginating easy and reusable (eg. `GET /users?_limit=30&name=John`).
|
||||
|
||||
> Please refer to the [filters' guide](../guides/filters.md) for more informations.
|
||||
|
||||
|
||||
@ -137,16 +137,16 @@ In order to do so, you'll need to allow access to other users (identified as 'Gu
|
||||
|
||||
### List entries (GET)
|
||||
|
||||
To retrieve the list of products, use the `GET /your-content-type` route.
|
||||
To retrieve the list of products, use the `GET /products` route.
|
||||
|
||||
Generated APIs provide a handy way to filter and order queries. In that way, ordering products by price is as easy as `GET http://localhost:1337/product?_sort=price:asc`. For more informations, read the [filters documentation](../guides/filters.md)
|
||||
Generated APIs provide a handy way to filter and order queries. In that way, ordering products by price is as easy as `GET http://localhost:1337/products?_sort=price:asc`. For more informations, read the [filters documentation](../guides/filters.md)
|
||||
|
||||
Here is an example using jQuery.
|
||||
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'http://localhost:1337/product?_sort=price:asc', // Order by price.
|
||||
url: 'http://localhost:1337/products?_sort=price:asc', // Order by price.
|
||||
done: function(products) {
|
||||
console.log('Well done, here is the list of products: ', products);
|
||||
},
|
||||
@ -163,7 +163,7 @@ If you want to get a specific entry, add the `id` of the wanted product at the e
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'http://localhost:1337/product/123', // Where `123` is the `id` of the product.
|
||||
url: 'http://localhost:1337/products/123', // Where `123` is the `id` of the product.
|
||||
done: function(product) {
|
||||
console.log('Well done, here is the product having the `id` 123: ', product);
|
||||
},
|
||||
@ -182,7 +182,7 @@ jQuery example:
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'http://localhost:1337/product',
|
||||
url: 'http://localhost:1337/products',
|
||||
data: {
|
||||
name: 'Cheese cake',
|
||||
description: 'Chocolate cheese cake with ice cream',
|
||||
@ -206,7 +206,7 @@ jQuery example:
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'PUT',
|
||||
url: 'http://localhost:1337/product/123', // Where `123` is the `id` of the product.
|
||||
url: 'http://localhost:1337/products/123', // Where `123` is the `id` of the product.
|
||||
data: {
|
||||
description: 'This is the new description'
|
||||
},
|
||||
@ -228,7 +228,7 @@ jQuery example:
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: 'http://localhost:1337/product/123', // Where `123` is the `id` of the product.
|
||||
url: 'http://localhost:1337/products/123', // Where `123` is the `id` of the product.
|
||||
done: function(product) {
|
||||
console.log('Congrats, your product has been successfully deleted: ', product);
|
||||
},
|
||||
|
||||
@ -97,7 +97,7 @@ By default, each API request is identified as `guest` role (see permissions of `
|
||||
```js
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'http://localhost:1337/article',
|
||||
url: 'http://localhost:1337/articles',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
|
||||
@ -29,11 +29,11 @@ Easily filter results according to fields values.
|
||||
|
||||
Find users having `John` as first name.
|
||||
|
||||
`GET /user?firstName=John`
|
||||
`GET /users?firstName=John`
|
||||
|
||||
Find products having a price equal or greater than `3`.
|
||||
|
||||
`GET /product?price_gte=3`
|
||||
`GET /products?price_gte=3`
|
||||
|
||||
### Sort
|
||||
|
||||
@ -43,8 +43,8 @@ Sort according to a specific field.
|
||||
|
||||
Sort users by email.
|
||||
|
||||
- ASC: `GET /user?_sort=email:asc`
|
||||
- DESC: `GET /user?_sort=email:desc`
|
||||
- ASC: `GET /users?_sort=email:asc`
|
||||
- DESC: `GET /users?_sort=email:desc`
|
||||
|
||||
### Limit
|
||||
|
||||
@ -54,7 +54,7 @@ Limit the size of the returned results.
|
||||
|
||||
Limit the result length to 30.
|
||||
|
||||
`GET /user?_limit=30`
|
||||
`GET /users?_limit=30`
|
||||
|
||||
### Start
|
||||
|
||||
@ -64,7 +64,7 @@ Skip a specific number of entries (especially useful for pagination).
|
||||
|
||||
Get the second page of results.
|
||||
|
||||
`GET /user?_start=10&_limit=10`
|
||||
`GET /users?_start=10&_limit=10`
|
||||
|
||||
## Programmatic usage
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ The global policies can be associated to any routes in your project.
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/car",
|
||||
"path": "/cars",
|
||||
"handler": "Car.find",
|
||||
"config": {
|
||||
"policies": [
|
||||
@ -66,7 +66,7 @@ Plugins can add and expose policies into your app. For example, the plugin `Auth
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/car",
|
||||
"path": "/cars",
|
||||
"handler": "Car.find",
|
||||
"config": {
|
||||
"policies": [
|
||||
@ -102,7 +102,7 @@ module.exports = async (ctx, next) => {
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/car",
|
||||
"path": "/cars",
|
||||
"handler": "Car.find",
|
||||
"config": {
|
||||
"policies": [
|
||||
|
||||
@ -12,17 +12,17 @@ You have to edit the `routes.json` file in one of your APIs folders (`./api/**/c
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/product",
|
||||
"path": "/products",
|
||||
"handler": "Product.find",
|
||||
},
|
||||
{
|
||||
"method": ["POST", "PUT"],
|
||||
"path": "/product/:id",
|
||||
"path": "/products/:id",
|
||||
"handler": "Product.createOrUpdate",
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/product/:id/buy",
|
||||
"path": "/products/:id/buy",
|
||||
"handler": "Product.buy",
|
||||
"config": {
|
||||
"policies": ["isAuthenticated", "hasCreditCard"]
|
||||
@ -33,7 +33,7 @@ You have to edit the `routes.json` file in one of your APIs folders (`./api/**/c
|
||||
```
|
||||
|
||||
- `method` (string): Method or array of methods to hit the route (ex: `GET`, `POST`, `PUT`, `HEAD`, `DELETE`, `PATCH`)
|
||||
- `path` (string): URL starting with `/` (ex: `/product`)
|
||||
- `path` (string): URL starting with `/` (ex: `/products`)
|
||||
- `handler` (string): Action to executed when the route is hit following this syntax `<Controller>.<action>`
|
||||
- `config`
|
||||
- `policies` (array): Array of policies names or path ([see more](../guides/policies.md))
|
||||
@ -48,12 +48,12 @@ The router used by Strapi allows you to create dynamic routes where you can use
|
||||
"routes": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/product/:category/:id",
|
||||
"path": "/products/:category/:id",
|
||||
"handler": "Product.findOneByCategory",
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/product/:region(\\d{2}|\\d{3})/:id", // Only match when the first parameter contains 2 or 3 digits.
|
||||
"path": "/products/:region(\\d{2}|\\d{3})/:id", // Only match when the first parameter contains 2 or 3 digits.
|
||||
"handler": "Product.findOneByRegion",
|
||||
}
|
||||
]
|
||||
|
||||
@ -21,42 +21,42 @@ module.exports = scope => {
|
||||
const routes = {
|
||||
routes: [{
|
||||
method: 'GET',
|
||||
path: '/' + scope.humanizeId,
|
||||
path: '/' + scope.idPluralized,
|
||||
handler: scope.globalID + '.find',
|
||||
config: {
|
||||
policies: []
|
||||
}
|
||||
}, {
|
||||
method: 'GET',
|
||||
path: '/' + scope.humanizeId + '/count',
|
||||
path: '/' + scope.idPluralized + '/count',
|
||||
handler: scope.globalID + '.count',
|
||||
config: {
|
||||
policies: []
|
||||
}
|
||||
}, {
|
||||
method: 'GET',
|
||||
path: '/' + scope.humanizeId + '/:' + tokenID,
|
||||
path: '/' + scope.idPluralized + '/:' + tokenID,
|
||||
handler: scope.globalID + '.findOne',
|
||||
config: {
|
||||
policies: []
|
||||
}
|
||||
}, {
|
||||
method: 'POST',
|
||||
path: '/' + scope.humanizeId,
|
||||
path: '/' + scope.idPluralized,
|
||||
handler: scope.globalID + '.create',
|
||||
config: {
|
||||
policies: []
|
||||
}
|
||||
}, {
|
||||
method: 'PUT',
|
||||
path: '/' + scope.humanizeId + '/:' + tokenID,
|
||||
path: '/' + scope.idPluralized + '/:' + tokenID,
|
||||
handler: scope.globalID + '.update',
|
||||
config: {
|
||||
policies: []
|
||||
}
|
||||
}, {
|
||||
method: 'DELETE',
|
||||
path: '/' + scope.humanizeId + '/:' + tokenID,
|
||||
path: '/' + scope.idPluralized + '/:' + tokenID,
|
||||
handler: scope.globalID + '.destroy',
|
||||
config: {
|
||||
policies: []
|
||||
@ -67,21 +67,21 @@ module.exports = scope => {
|
||||
if (scope.args.tpl && scope.args.tpl !== 'mongoose') {
|
||||
routes.routes.push({
|
||||
method: 'POST',
|
||||
path: '/' + scope.humanizeId + '/:' + tokenID + '/relationships/:relation',
|
||||
path: '/' + scope.idPluralized + '/:' + tokenID + '/relationships/:relation',
|
||||
handler: scope.globalID + '.createRelation',
|
||||
config: {
|
||||
policies: []
|
||||
}
|
||||
}, {
|
||||
method: 'PUT',
|
||||
path: '/' + scope.humanizeId + '/:' + tokenID + '/relationships/:relation',
|
||||
path: '/' + scope.idPluralized + '/:' + tokenID + '/relationships/:relation',
|
||||
handler: scope.globalID + '.updateRelation',
|
||||
config: {
|
||||
policies: []
|
||||
}
|
||||
}, {
|
||||
method: 'DELETE',
|
||||
path: '/' + scope.humanizeId + '/:' + tokenID + '/relationships/:relation',
|
||||
path: '/' + scope.idPluralized + '/:' + tokenID + '/relationships/:relation',
|
||||
handler: scope.globalID + '.destroyRelation',
|
||||
config: {
|
||||
policies: []
|
||||
|
||||
@ -9,5 +9,8 @@
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": true
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,5 +9,8 @@
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,5 +9,8 @@
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
||||
}
|
||||
|
||||
// Check if user is adding a relation with the same content type
|
||||
|
||||
|
||||
if (includes(this.props.hash, 'attributerelation') && this.props.modifiedDataAttribute.params.target === this.props.modelName && get(this.props.modifiedDataAttribute, ['params', 'nature'], '') !== 'oneWay') {
|
||||
// Insert two attributes
|
||||
this.props.addAttributeRelationToContentType(this.props.modifiedDataAttribute);
|
||||
@ -418,7 +418,7 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
||||
if (includes(this.props.hash, 'choose')) {
|
||||
const { nodeToFocus } = this.state;
|
||||
let toAdd = 0;
|
||||
|
||||
|
||||
switch(e.keyCode) {
|
||||
case 37: // Left arrow
|
||||
case 39: // Right arrow
|
||||
@ -446,7 +446,7 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
||||
toAdd = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
this.setState(prevState => ({ nodeToFocus: prevState.nodeToFocus + toAdd }));
|
||||
}
|
||||
}
|
||||
@ -456,7 +456,6 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
||||
const hashArray = split(this.props.hash, ('::'));
|
||||
const valueToReplace = includes(this.props.hash, '#create') ? '#create' : '#edit';
|
||||
const contentTypeName = replace(hashArray[0], valueToReplace, '');
|
||||
|
||||
let cbSuccess;
|
||||
let dataSucces = null;
|
||||
let cbFail;
|
||||
@ -466,7 +465,7 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
||||
// Check if the user is editing the attribute
|
||||
const isAttribute = includes(hashArray[1], 'attribute');
|
||||
cbSuccess = isAttribute ? () => this.editTempContentTypeAttribute(redirectToChoose) : this.createContentType;
|
||||
dataSucces = isAttribute ? null : this.props.modifiedDataEdit;
|
||||
dataSucces = isAttribute ? null : this.getModelWithCamelCaseName(this.props.modifiedDataEdit);
|
||||
cbFail = isAttribute ? () => this.editContentTypeAttribute(redirectToChoose) : this.contentTypeEdit;
|
||||
return this.testContentType(contentTypeName, cbSuccess, dataSucces, cbFail);
|
||||
}
|
||||
@ -476,11 +475,24 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
||||
return this.testContentType(contentTypeName, cbSuccess, dataSucces, cbFail);
|
||||
}
|
||||
default: {
|
||||
return this.createContentType(this.props.modifiedData);
|
||||
return this.createContentType(
|
||||
this.getModelWithCamelCaseName(this.props.modifiedData)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getModelWithCamelCaseName = (model = {}) => {
|
||||
if (isEmpty(model) || isEmpty(model.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
...model,
|
||||
name: camelCase(model.name),
|
||||
};
|
||||
}
|
||||
|
||||
initComponent = (props, condition) => {
|
||||
if (!isEmpty(props.hash)) {
|
||||
this.setState({ showModal: true });
|
||||
@ -514,7 +526,7 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
||||
}
|
||||
|
||||
renderModalBodyChooseAttributes = () => {
|
||||
const attributesDisplay = has(this.context.plugins.toJS(), 'upload')
|
||||
const attributesDisplay = has(this.context.plugins.toJS(), 'upload')
|
||||
? forms.attributesDisplay.items
|
||||
: forms.attributesDisplay.items.filter(obj => obj.type !== 'media'); // Don't display the media field if the upload plugin isn't installed
|
||||
|
||||
|
||||
@ -28,9 +28,9 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
let options = ctx.request.body;
|
||||
let options = ctx.request.body;
|
||||
|
||||
await strapi.plugins.email.services.send(options, config);
|
||||
await strapi.plugins.email.services.email.send(options, config);
|
||||
|
||||
// Send 200 `ok`
|
||||
ctx.send({});
|
||||
@ -48,7 +48,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
getSettings: async (ctx) => {
|
||||
let config = await strapi.plugins.email.services.email.getProviderConfig(ctx.params.environment);
|
||||
let config = await strapi.plugins.email.services.email.getProviderConfig(ctx.params.environment);
|
||||
|
||||
ctx.send({
|
||||
providers: strapi.plugins.email.config.providers,
|
||||
|
||||
@ -113,14 +113,16 @@ button {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.flexed {
|
||||
.flexed,
|
||||
.label {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.label {
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
width: 15rem;
|
||||
height: 5.2rem;
|
||||
line-height: 5.2rem;
|
||||
margin-left: 5rem;
|
||||
color: #333740;
|
||||
font-weight: 600;
|
||||
|
||||
@ -211,10 +211,9 @@
|
||||
"prefix": ""
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/user",
|
||||
"path": "/users",
|
||||
"handler": "User.find",
|
||||
"config": {
|
||||
"policies": [],
|
||||
@ -223,7 +222,7 @@
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/user/me",
|
||||
"path": "/users/me",
|
||||
"handler": "User.me",
|
||||
"config": {
|
||||
"policies": [],
|
||||
@ -232,7 +231,7 @@
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/user/:_id",
|
||||
"path": "/users/:_id",
|
||||
"handler": "User.findOne",
|
||||
"config": {
|
||||
"policies": [],
|
||||
@ -241,7 +240,7 @@
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/user",
|
||||
"path": "/users",
|
||||
"handler": "User.create",
|
||||
"config": {
|
||||
"policies": [],
|
||||
@ -250,7 +249,7 @@
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/user/:_id",
|
||||
"path": "/users/:_id",
|
||||
"handler": "User.update",
|
||||
"config": {
|
||||
"policies": [],
|
||||
@ -259,7 +258,7 @@
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"path": "/user/:_id",
|
||||
"path": "/users/:_id",
|
||||
"handler": "User.destroy",
|
||||
"config": {
|
||||
"policies": [],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user