diff --git a/docs/3.x.x/en/SUMMARY.md b/docs/3.x.x/en/SUMMARY.md
index 163636c53f..1db11a45b3 100644
--- a/docs/3.x.x/en/SUMMARY.md
+++ b/docs/3.x.x/en/SUMMARY.md
@@ -34,7 +34,7 @@
* [Advanced usage](plugins/advanced.md)
### Guides - Advanced
-* [Admin panel](guides-advanced/customize-admin.md)
+* [Admin panel](advanced/customize-admin.md)
* [Hooks](advanced/hooks.md)
* [Logging](advanced/logging.md)
* [Middlewares](advanced/middlewares.md)
diff --git a/docs/3.x.x/en/guides-advanced/customize-admin.md b/docs/3.x.x/en/advanced/customize-admin.md
similarity index 65%
rename from docs/3.x.x/en/guides-advanced/customize-admin.md
rename to docs/3.x.x/en/advanced/customize-admin.md
index 8ae88f4129..61f9842538 100644
--- a/docs/3.x.x/en/guides-advanced/customize-admin.md
+++ b/docs/3.x.x/en/advanced/customize-admin.md
@@ -7,26 +7,29 @@ See the [Contributing Guide](https://github.com/strapi/strapi/blob/master/.githu
## Files structure
The entire logic of the admin panel is located in a single folder named `./admin/`. This directory contains the following structure:
- - `admin/`:
- - `build/`: build of the front-end part generated by Webpack.
- - `src/`: source code of the front-end part.
- - `app.js`: entry point of the React application.
- - `assets/`: contains necessary assets (images…).
- - `components/`: contains components used by the admin panel.
- - `containers/`: contains high level components.
- - `favicon.ico`: favicon displayed in the web browser.
- - `i18n.js`: logic for internationalization.
- - `index.html`: basic html file in which are injected necessary styles and scripts.
- - `reducers.js`: reducers logic.
- - `store.js` store logic.
- - `styles/`: contains the global styles. Specific styles are defined at the component level.
- - `translations/`: text messages for each supported languages.
- - `config/`:
- - `routes.json`: admin panel API routes.
- - `admin.json`: contains admin panel specific settings.
- - `controllers/`: admin panel API controllers.
- - `package.json`: contains admin panel dependencies list.
- - `services/`: admin panel API services.
+```
+/admin
+└─── admin
+| └─── build // Webpack generated build of the front-end
+| └─── src // Front-end directory
+| └─── app.js // Entry point of the Reacr application
+| └─── assets // Assets directory containing images,...
+| └─── components // Admin's React components directory
+| └─── containers // Admin's high level components directory
+| └─── favicon.ico // Favicon displayed in web browser
+| └─── i18n.js // Internalization logic
+| └─── index.html // Basic html file in which are injected necessary styles and scripts
+| └─── reducers.js // Redux reducers logic
+| └─── store.js // Redux store logic
+| └─── styles // Directory containing the global styles. Specific styles are defined at the component level
+| └─── translations // Directory containing text messages for each supported languages
+└─── config
+| └─── routes.json // Admin's API routes
+| └─── admin.json // Admin's specific settings
+└─── controllers // Admin's API controllers
+└─── services // Admin's API services
+└─── packages.json // Admin's npm dependencies
+```
## Customization
diff --git a/docs/3.x.x/en/plugins/advanced.md b/docs/3.x.x/en/plugins/advanced.md
index f30fd76ef7..bd72c85ccc 100644
--- a/docs/3.x.x/en/plugins/advanced.md
+++ b/docs/3.x.x/en/plugins/advanced.md
@@ -319,6 +319,8 @@ const shouldRenderCompo = (plugin) => new Promise((resolve, request) => {
export default shouldRenderCompo;
```
+***
+
## Using React/Redux and sagas
If your application is going to interact with some back-end application for data, we recommend using redux saga for side effect management.
diff --git a/docs/3.x.x/en/tools/plugin-left-menu.md b/docs/3.x.x/en/plugins/plugin-left-menu.md
similarity index 100%
rename from docs/3.x.x/en/tools/plugin-left-menu.md
rename to docs/3.x.x/en/plugins/plugin-left-menu.md
diff --git a/docs/3.x.x/en/tools/button-library.md b/docs/3.x.x/en/tools/button-library.md
deleted file mode 100644
index 21c5cc7643..0000000000
--- a/docs/3.x.x/en/tools/button-library.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Button library
-
-Button library based on bootstrap classes
-
-## Usage
-
-| Property | Type | Required | Description
-:---| :---| :---| :---
-| `children`| node | no | Ex: `` |
-| `className`| any | no | Sets a custom className. Ex: `` |
-| `kind` | string | no | Sets the built-in className to the button. Ex: `` |
-| `label` | string | no | Sets the button label with i18n Ex: `` |
-| `labelValue` | string | no | Sets the button label with i18n and a dynamic value Ex: `` |
-| `loader` | bool | no | Displays a button loader. Ex: `` |
-| `primary` | bool | no | [Bootstrap className](https://v4-alpha.getbootstrap.com/components/buttons/) |
-| `primaryAddShape` | bool | no | Inserts fontAwesone plus icon inside the button. Ex: `` |
-| `secondary`| bool | no | [Bootstrap className](https://v4-alpha.getbootstrap.com/components/buttons/) |
-| `secondaryHotline` | bool | no | Sets className |
-| `secondaryHotlineAdd` | bool | no | Inserts fontAwesone plus icon inside the button. Ex: `` |
-| `type` | string | no | Sets the button type |
diff --git a/docs/3.x.x/en/tools/i18n.md b/docs/3.x.x/en/tools/i18n.md
deleted file mode 100644
index d45041314f..0000000000
--- a/docs/3.x.x/en/tools/i18n.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# i18n
-
-[React Intl](https://github.com/yahoo/react-intl) provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.
-
-## Usage
-
-We recommend to set all your components text inside the translations folder.
-
-The example below shows how to use i18n inside your plugin.
-
-### Define all your ids with the associated message
-
-`// my-plugin/admin/src/translations/en.json`
-
-```json
-{
- "notification.error.message": "An error occurred"
-}
-```
-
-`// my-plugin/admin/src/translations/fr.json`
-
-```json
-{
- "notification.error.message": "Une erreur est survenue"
-}
-```
-
-### Usage inside a component
-
-Basic usage :
-
-```js
-import { FormattedMessage } from 'react-intl';
-
-const Foo = (props) => (
-
-
-
-
-)
-
-export default Foo;
-```
-
-[Check out the documentation](https://github.com/yahoo/react-intl/wiki/Components#formattedmessage) for more extensive usage.
diff --git a/docs/3.x.x/en/tools/input-library.md b/docs/3.x.x/en/tools/input-library.md
deleted file mode 100644
index 41946c0125..0000000000
--- a/docs/3.x.x/en/tools/input-library.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Input Library
-
-Strapi provides a built-in input library which includes :
- - All kind of inputs
- - Front-End validations
- - Error highlight
- - i18n
- - ...
-
-## Usage
-
-```js
-import React from 'react';
-// The library is available under node_modules/strapi-helper-plugin/src/components/Input
-import Input from 'components/Input';
-
-class Foo extends React.Component {
- constructor(props) {
- super(props);
-
- this.state {
- data: {
- foo: 'bar',
- },
- error: false,
- errors: [],
- };
- }
-
- handleChange = ({ target }) => {
- const value = target.type === 'number' ? Number(target.value) : target.value;
-
- const error = target.value.length === 0;
-
- if (error) {
- this.setState({ error: !this.state.error, errors: [{ id: 'This input is required ' }] });
- } else {
- this.setState({ data[target.name]: value });
- }
-
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
-```
-
-### Usage
-
-| Property | Type | Required | Description
-:---| :---| :---| :---
-| `addon` | string | no | Allows to add a string addon in your input, based on [Bootstrap](https://v4-alpha.getbootstrap.com/components/input-group/#basic-example). Ex: `` |
-| `addRequiredInputDesign` | bool | no | Allows to add an asterix on the input. Ex: `` |
-| `customBootstrapClass` | string | no | Allows to override the input bootstrap col system. Ex: `` |
-| `deactivateErrorHighlight` | bool | no | Prevents from displaying error highlight in the input: Ex: `` |
-| `didCheckErrors` | bool | no | Use this props to display errors after submitting a form. Ex: `` |
-| `disabled` | bool | no | Disable the input. Ex: `` |
-| `errors` | array | no | Allows to display custom error messages. Ex: `` |
-| `handleBlur` | func or bool | no | Overrides the default onBlur behavior. If bool passed to the component it will disabled the input validations checking. |
-| `handleChange` | func | yes | Sets your reducer state. |
-| `handFocus` | func | no | Adds an onFocus event to the input. |
-| `inputDescription` | string | no | Allows to add an input description that is displayed like [bootstrap](https://v4-alpha.getbootstrap.com/components/forms/#defining-states). |
-| `label` | string | yes | Displays the input's label with i18n |
-| `linkContent` | object | no | Allows to display a link within the input's description. Ex: ``|
-| `name` | string | yes | The key to update your reducer. |
-| `noErrorsDescription` | bool | no | Prevents from displaying built-in errors. |
-| `placeholder` | string | no | Allows to set a placeholder. |
-| `pluginId` | string | no | Use to display name, placeholder... with i18n. |
-| `selectOptions` | array | no | Options for the select. |
-| `tabIndex` | string | no | Sets the order in which the inputs are focused on tab key press. |
-| `title` | string | no | This props can only be used for checkboxes, it allows to add a title on top of the input, the label will be on the right side of the checkbox. |
-| `validations` | object | yes | Allows to have the built-in input's validations. If set to {} the validations will be ignored. Ex: `` |
-| `value` | string or bool or number | yes | The input's value. |
diff --git a/docs/3.x.x/en/tools/prevent-plugin-rendering.md b/docs/3.x.x/en/tools/prevent-plugin-rendering.md
deleted file mode 100644
index 6fc005eef3..0000000000
--- a/docs/3.x.x/en/tools/prevent-plugin-rendering.md
+++ /dev/null
@@ -1,127 +0,0 @@
-# Prevent a plugin from being rendered
-
-You can prevent your plugin from being rendered if some conditions aren't met.
-
-## Usage
-
-To disable your plugin's rendering, you can simply create `requirements.js` file at the root of your `src` plugin's folder.
-This file must contain a default function that returns a `Promise`;
-
-Example:
-
-Let's say that you want to disable your plugin if the server autoReload config is disabled in development mode.
-
-
-```
-// config/environments/development/server.json
-{
- "host": "localhost",
- "port": 1337,
- "cron": {
- "enabled": false
- }
-}
-```
-
-You'll first create a request to check if the `autoReload` config is enabled.
-
-```json
-// plugins/my-plugin/config/routes.json
-{
- "routes": [
- {
- "method": "GET",
- "path": "/autoReload",
- "handler": "MyPlugin.autoReload",
- "config": {
- "policies": []
- }
- }
- ]
-}
-```
-Then the associated handler:
-
-```js
-// plugins/my-plugin/controllers/MyPlugin.js
-
-const _ = require('lodash');
-const send = require('koa-send');
-
-module.exports = {
- autoReload: async ctx => {
- ctx.send({ autoReload: _.get(strapi.config.environments, 'development.server.autoReload', false) });
- }
-}
-```
-
-Finally, you'll create a file called `requirements.js`at the root of your plugin's src folder.
-
-The default function exported must return a `Promise`.
-If you wan't to prevent the plugin from being rendered you'll have to set `plugin.preventComponentRendering = true;`.
-In this case, you'll have to set:
-```js
-plugin.blockerComponentProps = {
- blockerComponentTitle: 'my-plugin.blocker.title',
- blockerComponentDescription: 'my-plugin.blocker.description',
- blockerComponentIcon: 'fa-refresh',
-};
-```
-
-To follow the example above:
-
-```js
-// plugin/my-plugin/admin/src/requirements.js
-
-// Use our request helper
-import request from 'utils/request';
-
-const shouldRenderCompo = (plugin) => new Promise((resolve, request) => {
- request('/my-plugin/autoReload')
- .then(response => {
- // If autoReload is enabled the response is `{ autoReload: true }`
- plugin.preventComponentRendering = !response.autoReload;
- // Set the BlockerComponent props
- plugin.blockerComponentProps = {
- blockerComponentTitle: 'my-plugin.blocker.title',
- blockerComponentDescription: 'my-plugin.blocker.description',
- blockerComponentIcon: 'fa-refresh',
- blockerComponentContent: 'renderIde', // renderIde will add an ide section that shows the development environment server.json config
- };
-
- return resolve(plugin);
- })
- .catch(err => reject(err));
-});
-
-export default shouldRenderCompo;
-```
-## Customization
-
-You can render your own custom blocker by doing as follows:
-
-```js
-// plugin/my-plugin/admin/src/requirements.js
-
-// Use our request helper
-import request from 'utils/request';
-
-// Your custom blockerComponentProps
-import MyCustomBlockerComponent from 'components/MyCustomBlockerComponent';
-
-const shouldRenderCompo = (plugin) => new Promise((resolve, request) => {
- request('/my-plugin/autoReload')
- .then(response => {
- // If autoReload is enabled the response is `{ autoReload: true }`
- plugin.preventComponentRendering = !response.autoReload;
-
- // Tell which component to be rendered instead
- plugin.blockerComponent = MyCustomBlockerComponent;
-
- return resolve(plugin);
- })
- .catch(err => reject(err));
-});
-
-export default shouldRenderCompo;
-```
diff --git a/docs/3.x.x/en/tools/router.md b/docs/3.x.x/en/tools/router.md
deleted file mode 100644
index 81ed481e9e..0000000000
--- a/docs/3.x.x/en/tools/router.md
+++ /dev/null
@@ -1,279 +0,0 @@
-# Using the React Router V4
-
-User navigation within your plugin can be managed by two different ways :
- - Using the [React Router V4 API](https://reacttraining.com/react-router/web/guides/philosophy)
- - Using the main router from the app
-
-## Routing declaration
-
-### Routing
-
-The routing is based on [React Router V4](https://reacttraining.com/react-router/web/guides/philosophy), due to it's implementation each route is declared in the containers/App/index.js file.
-
-Also, we chose to use the [Switch Router](https://reacttraining.com/react-router/web/api/Switch) because it renders a route exclusively.
-
-Route declaration :
-
-Let's say that you want to create a route /user with params /:id associated with the container User.
-
-The declaration would be as followed :
-
-
- ```js
- // File : `plugins/my-plugin/admin/src/containers/App/index.js`.
-
- import UserPage from 'containers/UserPage'
-
- // ...
-
- render() {
- return (
-
-
-
-
-
- );
- }
- ```
-
-
-### Using Redux/sagas
-
-Due to React Router V4 your container's store is not directly injected.
-To inject your container store if it's associated with a router you have to do it manually.
-
-As an example, you created a Foo container associated with the route `/plugins/my-plugin/bar`, and you want to use redux/action/reducer/sagas.
-
-Your `plugins/my-plugin/admin/src/containers/App/index.js` file will look as followed :
-
-```js
-// plugins/my-plugin/admin/src/containers/App/index.js
-
-import FooPage from 'containers/FooPage'
-
-// ...
-
-render() {
- return (
-
-
-
-
-
- );
-
-}
-```
-
-```js
-// plugins/my-plugin/admin/src/containers/FooPage/index.js
-
-import React from 'react';
-import { connect } from 'react-redux';
-import { createStructuredSelector } from 'reselect';
-import { bindActionCreators, compose } from 'redux';
-import PropTypes from 'prop-types';
-
-// Utils to create your container store
-import injectReducer from 'utils/injectReducer';
-import injectSaga from 'utils/injectSaga';
-
-import {
- foo,
- bar,
-} from './actions';
-
-import reducer from './reducer';
-
-import saga from './sagas';
-import { makeSelectFooPage } from './selectors';
-
-// Styles
-import styles from './styles.scss';
-
-export class FooPage extends React.Component {
- render() {
- return (
-
- Awesome container
-
- );
- }
-}
-
-FooPage.propTypes = {
- fooPage: PropTypes.any,
-}
-
-function mapDispatchToProps(dispatch) {
- return bindActionCreators(
- {
- foo,
- bar,
- },
- dispatch
- );
-}
-
-const mapStateToProps = createStructuredSelector({
- fooPage: makeSelectFooPage(),
-});
-
-const withConnect = connect(mapStateToProps, mapDispatchToProps);
-
-// This is where you create your container store
-// the key must correspond to your container name in lowerCase
-const withSagas = injectSaga({ key: 'fooPage', saga });
-const withReducer = injectReducer({ key: 'fooPage', reducer });
-
-export default compose(
- withReducer,
- withSagas,
- withConnect,
-)(FooPage);
-```
-
-
-Important : If you have a container which can be a child of several other containers (i.e. it doesn't have a route), in order to create the store
-you'll have to inject it directly in the `plugins/my-plugin/admin/src/containers/App/index.js` file as follows :
-
-```js
-// containers/App/index.js
-
-// ...
-
-import fooPageReducer from 'containers/FooPage/reducer';
-import fooPageSagas from 'container/FooPage/sagas';
-
-import reducer from './reducer';
-import saga from './sagas';
-
-// ...
-
-export class App extends React.Component {
- render() {
- // ...
- }
-}
-
-// ...
-
-function mapDispatchToProps(dispatch) {
- return bindActionCreators(
- {},
- dispatch
- );
-}
-
-const mapStateToProps = createStructuredSelector({
- // ...
-});
-
-const withConnect = connect(mapStateToProps, mapDispatchToProps);
-
-// FooPage reducer
-const withFooPageReducer = injectReducer({ key: 'fooPage', reducer: fooPageReducer });
-// Global reducer
-const withReducer = injectReducer({ key: 'global', reducer });
-// FooPage sagas
-const withFooPageSagas = injectSaga({ key: 'fooPage', saga: fooPageSagas });
-// Global saga
-const withSagas = injectSaga({ key: 'global', saga });
-
-export default compose(
- withFooPageReducer,
- withReducer,
- withFooPageSagas,
- withSagas,
- withConnect,
-)(App);
-```
-
-## Using React Router
-
- [Link](https://reacttraining.com/react-router/web/api/Link) provides declarative, accessible navigation around your application :
-
- ```js
-
-
- // Same as
-
-
- ```
-
- [NavLink](https://reacttraining.com/react-router/web/api/NavLink) will add styling attributes to the rendered element when it matches the current URL.
-
-
- ```js
- FAQs
- ```
-## Using the App Router
-
-We use the app router if we want to make a redirection after some user's action (ex: after submitting a form).
-
-```js
-import React from 'react';
-import { bindActionCreators } from 'redux';
-import { connect, compose } from 'react-redux';
-import PropTypes from 'prop-types';
-
-// App router
-import { router } from 'app';
-
-// Utils
-import injectSaga from 'utils/injectSaga';
-import injectReducer from 'utils/injectReducer';
-
-// Actions
-import { foo, bar } from './actions';
-// Sagas
-import saga from './sagas';
-// Selectors
-import selectFoo from './Selectors';
-// Reducer
-import reducer from './reducer';
-
-export class Foo extends React.Component {
- componentWillReceiveProps(nextProps) {
- if (nextProps.foo !== this.props.foo) {
- const hash = this.props.location.hash;
- const pathname = this.props.match.pathname;
- const search = '?foo=bar';
- router.push({ pathname, search, hash });
- }
- }
-
- render() {
- return
Hello
;
- }
-}
-Foo.propTypes = {
- foo: PropTypes.bool.isRequired,
- location: PropTypes.object.isRequired,
- match: PropTypes.object.isRequired,
-};
-
-const mapStateToProps = selectFoo();
-
-function mapDispatchToProps(dispatch) {
- return bindActionCreators({}, dispatch);
-}
-
-const withConnect = connect(mapStateToProps, mapDispatchToProps);
-const withReducer = injectReducer({ key: 'foo', reducer });
-const withSagas = injectSaga({ key: 'foo', saga });
-
-export default compose(
- withReducer,
- withSagas,
- withConnect,
-)(Foo);
-```
diff --git a/docs/3.x.x/en/tools/using-actions-reducer-sagas.md b/docs/3.x.x/en/tools/using-actions-reducer-sagas.md
deleted file mode 100644
index 217ce58f59..0000000000
--- a/docs/3.x.x/en/tools/using-actions-reducer-sagas.md
+++ /dev/null
@@ -1,282 +0,0 @@
-# Redux saga
-
-If your application is going to interact with some back-end application for data, we recommend using redux saga for side effect management.
-
-## Example : fetching data on router change
-
-This example will show how to fetch data using actions/reducer/sagas.
-
-### Constants declaration
-
-```js
-// containers/Foo/constants.js
-export const DATA_FETCH = 'MyPlugin/Foo/DATA_FETCH';
-export const DATA_FETCH_ERROR = 'MyPlugin/Foo/DATA_FETCH_ERROR';
-export const DATA_FETCH_SUCCEEDED = 'MyPlugin/Foo/DATA_FETCH_SUCCEEDED';
-```
-
-### Actions declaration
-
-```js
-// containers/Foo/actions.js
-import {
- DATA_FETCH,
- DATA_FETCH_ERROR,
- DATA_FETCH_SUCCEEDED,
-} from './constants';
-
-export function dataFetch(params) {
- return {
- type: DATA_FETCH,
- params,
- };
-}
-
-export function dataFetchError(errorMessage) {
- return {
- type: DATA_FETCH_ERROR,
- errorMessage,
- };
-}
-
-export function dataFetchSucceeded(data) {
- return {
- type: DATA_FETCH_SUCCEEDED,
- data,
- };
-}
-```
-
-### Reducer
-
-We strongly recommend to use [Immutable.js](https://facebook.github.io/immutable-js/) to structure your data.
-
-```js
-// containers/Foo/reducer.js
-import { fromJS, Map } from 'immutable';
-import {
- DATA_FETCH_ERROR,
- DATA_FETCH_SUCCEEDED,
-} from './constants';
-
-const initialState = fromJS({
- data: Map({}),
- error: false,
- errorMessage: '',
- loading: true,
-});
-
-function fooReducer(state = initialState, action) {
- switch (action.type) {
- case DATA_FETCH_ERROR:
- return state
- .set('error', true)
- .set('errorMessage', action.errorMessage)
- .set('loading', false);
- case DATA_FETCH_SUCCEEDED:
- return state
- .set('data', Map(action.data))
- .set('error', false)
- .set('errorMessage', '')
- .set('loading', false);
- break;
- default:
- return state;
- }
-}
-
-export default fooReducer;
-```
-### Sagas
-
-```js
-// container/Foo/sagas.js
-import { takeLatest } from 'redux-saga';
-import { LOCATION_CHANGE } from 'react-router-redux';
-import { put, fork, call, take, cancel } from 'redux-saga/effects';
-
-// Use our request helper
-import { request } from 'utils/request';
-
-// Actions
-import { dataFetchError, dataFetchSucceeded } from './actions';
-import { DATA_FETCH } from './constants';
-
-export function* fetchData(action) {
- try {
- const requestUrl = `/baseUrl/${action.params}`;
- const opts = {
- method: 'GET',
- };
-
- // Fetch data
- const response = yield call(request, requestUrl, opts);
-
- // Pass the response to the reducer
- yield put(dataFetchSucceeded(response));
-
- } catch(error) {
- yield put(dataFetchError(error));
- }
-}
-
-// Individual export for testing
-function* defaultSaga() {
- // Listen to DATA_FETCH event
- const fetchDataWatcher = yield fork(takeLatest, DATA_FETCH, fetchData);
-
- // Cancel watcher
- yield take(LOCATION_CHANGE);
-
- yield cancel(fetchDataWatcher);
-}
-
-export default defaultSaga;
-```
-
-N.B. You can use a selector in your saga :
-
-```js
-import { put, select, fork, call, take, cancel } from 'redux-saga/effects';
-import { makeSelectUserName } from './selectors';
-
-export function* foo() {
- try {
- const userName = yield select(makeSelectUserName());
-
- // ...
- } catch(error) {
- // ...
- }
-}
-
-function defaultSaga() {
- // ...
-}
-
-export default defaultSaga;
-```
-
-
-### Selectors
-
-[Reselect](https://github.com/reactjs/reselect) is a library used for slicing your redux state and providing only the relevant sub-tree to a react component. It has three key features:
-
- 1. Computational power
- 2. Memoization
- 3. Composability
-
- Creating a selector
- ```js
- import { createSelector } from 'reselect';
-
- /**
- * Direct selector to the foo state domain
- */
- const selectFooDomain = () => state => state.get('foo');
-
- /**
- * Other specific selectors
- */
-
- const makeSelectLoading = () => createSelector(
- selectFooDomain(),
- (substate) => substate.get('loading'),
- );
-
- /**
- * Default selector used by ModelPage
- */
-
- const selectFoo = () => createSelector(
- selectFooDomain(),
- (substate) => substate.toJS()
- );
-
- export default selectFoo;
- export { makeSelectLoading };
-
- ```
-
-
-### INDEX.js
-
-```js
-// containers/Foo/index.js
-import React from 'react';
-import { bindActionCreators } from 'redux';
-import { connect, compose } from 'react-redux';
-import PropTypes from 'prop-types';
-
-// Main router
-import { router } from 'app';
-
-// Utils
-import injectSaga from 'utils/injectSaga';
-import injectReducer from 'utils/injectReducer';
-
-// Actions
-import { dataFetch } from './actions';
-// sagas
-import saga from './sagas';
-// Selectors
-import selectFoo from './selectors';
-// Reducer
-import reducer from './reducer';
-
-export class Foo extends React.Component {
- componentWillReceiveProps(nextProps) {
- if (this.props.error !== nextProps.error && nextProps.error) {
- window.Strapi.notification.error(this.props.errorMessage);
- }
- }
-
- componentDidUpdate(prevProps) {
- if (prevProps.match.pathname !== this.props.pathname) {
- this.props.dataFetch(this.props.match.params.bar);
- }
- }
-
- render() {
- if (this.props.error) return
An error occurred
;
-
- return (
-
-
Data display
- {this.props.data.foo}
- {this.props.data.bar}
-
- );
- }
-
- Foo.propTypes = {
- data: PropTypes.object.isRequired,
- dataFetch: PropTypes.func.isRequired,
- error: PropTypes.bool.isRequired,
- errorMessage: PropTypes.string.isRequired,
- match: PropTypes.object.isRequired,
- };
-
- const mapStateToProps = selectFoo();
-
- function mapDispatchToProps(dispatch) {
- return bindActionCreators(
- {
- dataFetch,
- },
- dispatch
- );
- }
-
- const withConnect = connect(mapStateToProps, mapDispatchToProps);
- const withReducer = injectReducer({ key: 'foo', reducer });
- const withSagas = injectSaga({ key: 'foo', saga });
-
- export default compose(
- withReducer,
- withSagas,
- withConnect,
- )(Foo);
-}
-
-```
diff --git a/docs/3.x.x/en/ui-components/component-button.md b/docs/3.x.x/en/ui-components/component-button.md
deleted file mode 100644
index b777578fc0..0000000000
--- a/docs/3.x.x/en/ui-components/component-button.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Component Button
-
-Button library based on bootstrap classes
-
-
-
-## Usage
-
-| Property | Type | Required | Description |
-| -------- | ---- | -------- | ----------- |
-| `children`| node | no | Ex: `` |
-| `className` | any | no | Sets a custom className. Ex: `` |
-| `kind` | string | no | Sets the built-in className to the button. Ex: `` |
-| `label` | string | no | Sets the button label with i18n Ex: `` |
-| `labelValue` | string | no | Sets the button label with i18n and a dynamic value Ex: {% raw %} `````` {% endraw %} |
-| `loader` | bool | no | Displays a button loader. Ex: `` |
-| `primary` | bool | no | [Bootstrap className](https://v4-alpha.getbootstrap.com/components/buttons/) |
-| `primaryAddShape` | bool | no | Inserts fontAwesone plus icon inside the button. Ex: `` |
-| `secondary`| bool | no | [Bootstrap className](https://v4-alpha.getbootstrap.com/components/buttons/) |
-| `secondaryHotline` | bool | no | Sets className |
-| `secondaryHotlineAdd` | bool | no | Inserts fontAwesone plus icon inside the button. Ex: `` |
-| `type` | string | no | Sets the button type |
-
-## Example
-
- **Path —** `./plugins/my-plugin/admin/src/translations/en.json`.
-```json
-{
- "myPlugin.button.label": "Add a new"
-}
-```
-
-**Path —** `./plugins/my-plugin/admin/src/components/Foo/index.js`.
-```js
-import Button from 'components/Button';
-
-const Foo = () => {
- // Define your buttons
- const buttons = [
- {
- label: 'myPlugin.button.label',
- labelValues: {
- foo: 'Bar',
- },
- kind: 'primaryAddShape',
- onClick: () => console.log('Click'),
- },
- ];
-
- return (
-
- {buttons.map((buttonProps) => }
-
- );
-}
-
-// Will display a primaryAddShape button with label: 'Add a new Bar'
-
-export default Button;
-```
diff --git a/docs/3.x.x/en/ui-components/component-input.md b/docs/3.x.x/en/ui-components/component-input.md
deleted file mode 100644
index de58657adb..0000000000
--- a/docs/3.x.x/en/ui-components/component-input.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Input Library
-
-Strapi provides a built-in input library which includes :
- - All kind of inputs
- - Front-End validations
- - Error highlight
- - i18n
-
-## Usage
-
-| Property | Type | Required | Description |
-| -------- | ---- | -------- | ----------- |
-| `addon` | string | no | Allows to add a string addon in your input, based on [Bootstrap](https://v4-alpha.getbootstrap.com/components/input-group/#basic-example). Ex: `` |
-| `addRequiredInputDesign` | bool | no | Allows to add an asterix on the input. Ex: `` |
-| `customBootstrapClass` | string | no | Allows to override the input bootstrap col system. Ex: `` |
-| `deactivateErrorHighlight` | bool | no | Prevents from displaying error highlight in the input: Ex: `` |
-| `didCheckErrors` | bool | no | Use this props to display errors after submitting a form. Ex: `` |
-| `disabled` | bool | no | Disable the input. Ex: `` |
-| `errors` | array | no | Allows to display custom error messages. Ex: `` |
-| `handleBlur` | func or bool | no | Overrides the default onBlur behavior. If bool passed to the component it will disabled the input validations checking. |
-| `handleChange` | func | yes | Sets your reducer state. |
-| `handFocus` | func | no | Adds an onFocus event to the input. |
-| `inputDescription` | string | no | Allows to add an input description that is displayed like [bootstrap](https://v4-alpha.getbootstrap.com/components/forms/#defining-states). |
-| `label` | string | yes | Displays the input's label with i18n. |
-| `linkContent` | object | no | Allows to display a link within the input's description. Ex: {% raw %} ``` ``` {% endraw %} |
-| `name` | string | yes | The key to update your reducer. |
-| `noErrorsDescription` | bool | no | Prevents from displaying built-in errors. |
-| `placeholder` | string | no | Allows to set a placeholder. |
-| `pluginId` | string | no | Use to display name, placeholder... with i18n. |
-| `selectOptions` | array | no | Options for the select. |
-| `tabIndex` | string | no | Sets the order in which the inputs are focused on tab key press. |
-| `title` | string | no | This props can only be used for checkboxes, it allows to add a title on top of the input, the label will be on the right side of the checkbox. |
-| `validations` | object | yes | Allows to have the built-in input's validations. If set to {} the validations will be ignored. Ex: {% raw %} ``` ``` {% endraw %} |
-| `value` | string or bool or number | yes | The input's value. |
-
-## Example
-
-```js
-import React from 'react';
-// The library is available under node_modules/strapi-helper-plugin/src/components/Input
-import Input from 'components/Input';
-
-class Foo extends React.Component {
- constructor(props) {
- super(props);
-
- this.state {
- data: {
- foo: 'bar',
- },
- error: false,
- errors: [],
- };
- }
-
- handleChange = ({ target }) => {
- const value = target.type === 'number' ? Number(target.value) : target.value;
-
- const error = target.value.length === 0;
-
- if (error) {
- this.setState({ error: !this.state.error, errors: [{ id: 'This input is required ' }] });
- } else {
- this.setState({ data[target.name]: value, error: false, errors: [] });
- }
-
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
-```
diff --git a/docs/3.x.x/en/ui-components/component-popup-warning.md b/docs/3.x.x/en/ui-components/component-popup-warning.md
deleted file mode 100644
index 35da247521..0000000000
--- a/docs/3.x.x/en/ui-components/component-popup-warning.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# PopUp Warning
-
-PopUp warning library based on [reactstrap](https://reactstrap.github.io/components/modals/).
-
-
-
-## Usage
-
-| Property | Type | Required | Description |
-| -------- | ---- | -------- | ----------- |
-| bodyMessage | string | no | Body message of the pop up (works with i18n). |
-| handleConfirm | func | yes | Function executed when the user clicks on the `Confirm button`. |
-| isOpen | bool | yes | Show or hide the popup. |
-| popUpWarningType | string | yes | Sets the popup body icon. Available types: `danger`, `info`, `notFound`, `success`, `warning` |
-| toggleModal | func | yes | Function to toggle the modal. |
-
-
-## Example
-
-**Path —** `./plugins/my-plugin/admin/src/translations/en.json`.
-```json
-{
- "button.label": "Click me",
- "popup.danger.message": "Are you sure you want to delete this item?"
-}
-```
-
-**Path —** `./plugins/my-plugin/admin/src/translations/fr.json`.
-```json
-{
- "button.label": "Cliquez",
- "popup.danger.message": "Êtes-vous certain de vouloir supprimer ce message?"
-}
-```
-
-**Path —** `./plugins/my-plugin/admin/src/containers/Foo/index.js`.
-```js
-// ...
-
-import Button from 'components/Button';
-import PopUpWarning from 'components/PopUpWarning';
-
-// ...
-
-class Foo extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- isOpen: false,
- };
- }
-
- handlePopUpConfirm = () => {
- // Some logic Here
- this.setState({ isOpen: false });
- }
-
- render() {
- return(
-
-
- );
- }
-}
-
-export default Foo;
-```
diff --git a/docs/3.x.x/en/usage/consume-api.md b/docs/3.x.x/en/usage/consume-api.md
deleted file mode 100644
index 95fb4ab229..0000000000
--- a/docs/3.x.x/en/usage/consume-api.md
+++ /dev/null
@@ -1,112 +0,0 @@
-# Consume your API
-
-Let's say you created a Product API with name, description and float fields.
-
-## List entries
-
-To retrieve the list of products, use `GET /your-content-type` route.
-
-Generated APIs provides a handy way to filter and order queries. That way, ordering products by price is as easy as `GET http://localhost:1337/product?_order=price:asc`. For more information, read the [filters documentation](todo.md).
-
-Here is an example using jQuery.
-
-```js
-$.ajax({
- type: 'GET',
- url: 'http://localhost:1337/product_order=price:asc', // Order by price.
- done: function(products) {
- console.log('Well done, here is the list of products: ', products);
- },
- fail: function(error) {
- console.log('An error occurred:', error);
- }
-});
-```
-
-## Get a specific entry
-
-If you want to get a specific entry, add the `id` of the wanted product at the end of the url.
-
-```js
-$.ajax({
- type: 'GET',
- url: 'http://localhost:1337/product/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);
- },
- fail: function(error) {
- console.log('An error occurred:', error);
- }
-});
-```
-
-## Create data (POST)
-
-Use the `POST` route to create a new entry.
-
-jQuery example:
-
-```js
-$.ajax({
- type: 'POST',
- url: 'http://localhost:1337/product',
- data: {
- name: 'Cheese cake',
- description: 'Chocolate cheese cake with ice cream',
- price: 5
- },
- done: function(product) {
- console.log('Congrats, your product has been successfully created: ', product); // Remember the product `id` for the next steps.
- },
- fail: function(error) {
- console.log('An error occurred:', error);
- }
-});
-```
-
-## Update data (PUT)
-
-Use the `PUT` route to update an existing entry.
-
-jQuery example:
-
-```js
-$.ajax({
- type: 'PUT',
- url: 'http://localhost:1337/product/123', // Where `123` is the `id` of the product.
- data: {
- description: 'This is the new description'
- },
- done: function(product) {
- console.log('Congrats, your product has been successfully updated: ', product.description);
- },
- fail: function(error) {
- console.log('An error occurred:', error);
- }
-});
-```
-
-## Delete data (DELETE)
-
-Use the `DELETE` route to delete an existing entry.
-
-jQuery example:
-
-```js
-$.ajax({
- type: 'DELETE',
- url: 'http://localhost:1337/product/123', // Where `123` is the `id` of the product.
- done: function(product) {
- console.log('Congrats, your product has been successfully deleted: ', product);
- },
- fail: function(error) {
- console.log('An error occurred:', error);
- }
-});
-```
-
-***
-
-Congratulations! You successfully finished the Getting Started guide! Read the [documentation](../admin.md) to understand more advanced concepts.
-
-Also, feel free to join the community thanks to the different channels listed in the [community page](/community): team members, contributors and developers will be happy to help you.
diff --git a/docs/3.x.x/en/usage/create-project.md b/docs/3.x.x/en/usage/create-project.md
deleted file mode 100644
index a1c300fcf5..0000000000
--- a/docs/3.x.x/en/usage/create-project.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Create your first project
-
-After having [installed Strapi](installation.md), you are now ready to create your first project.
-
-## Command Line
-
-The first step is to **open your terminal** in the directory you want to create your application in. Then, type
-
-```
-$ strapi new my-project
-```
-
-
-
-## Files structure
-
-This action creates a new folder named `my-project` with the entire [files structure](../API.md) of a Strapi application.
diff --git a/docs/3.x.x/en/usage/generate-api.md b/docs/3.x.x/en/usage/generate-api.md
deleted file mode 100644
index 56df9537fb..0000000000
--- a/docs/3.x.x/en/usage/generate-api.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Generate an API
-
-There is two ways to create an API:
- - Using the Content Type Builder plugin.
- - Using the CLI.
-
-## Content Type Builder
-
-The easiest way is to use the Content Type Builder plugin: a powerful UI to help you to create an API within a few clicks.
-
-To create your API using the Content Type Builder:
- - Start your project and visit the admin panel at the following address: http://localhost:1337/admin/plugins/content-type-builder.
- - Click on "Create Content Type", set `product` as name and submit the form.
- - Then, click on "Add fields", add the following fields:
- - A `string` field named `name`.
- - A `text` field named `description`.
- - A `float` field named `price`.
- - Save.
-
-That's it: your API is created!
-
-
-
-## CLI generator
-
-You can also use the [CLI](CLI.md) and its powerful generators.
-
-Type in your terminal the following command:
-
-```
-$ strapi generate:api product name:string description:text price:float
-```
-
-Here are some explanations:
- - `product` is the name of your Content Type.
- - `name`, `description` and `price` are the attributes.
- - `string`, `text` and `float` are the types of the attributes.
-
-For more information, read the [CLI documentation](CLI.md).
-
-
-
-### Files structure (I think we should remove this part)
-
-Whatever option you used to create your API, a new directory has been created in the `api` folder of your application which contains all the needed stuff for your `product` Content Type: API, routes, controller, service and model. Take a look at the [API structure documentation](API.md) for more informations.
diff --git a/docs/3.x.x/en/usage/manage-data.md b/docs/3.x.x/en/usage/manage-data.md
deleted file mode 100644
index 9d27a5c83e..0000000000
--- a/docs/3.x.x/en/usage/manage-data.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Manage data
-
-Let's say you created a Product API with name, description and price fields.
-
-In this section, we will discover the tool that Strapi provides to help you to manage your data.
-
-## Content Manager
-
-If you visit your admin panel at http://localhost:1337/admin, you can access to a plugin named Content Manager. This powerful interface is auto-generated according to your Content Types and lets you create, update and delete your data from UI.
-
-### Create a product
-
-Try to create a new product by clicking on "New entry". Give it a name, a description and a price. Submit the form. You can see the new product in the products list.
-
-### Edit a product
-
-From the list view, you can click on a product and edit its values.
-
-### Delete a product
-
-From the list view and the edit view, you can delete a product.
diff --git a/docs/3.x.x/en/usage/start-server.md b/docs/3.x.x/en/usage/start-server.md
deleted file mode 100644
index 4ec51b0252..0000000000
--- a/docs/3.x.x/en/usage/start-server.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Start your server
-
-To launch your app, go in its directory and run the following command:
-
-```
-$ strapi start
-```
-
-
-
-Visit http://localhost:1337 to see it live!
-
-You can also discover the admin panel at the following address: http://localhost:1337/admin.
-
-***
-
-Your server is up and running.