Merge branch 'master' into fix/vulnerabilityAlert
@ -1,12 +1,11 @@
|
|||||||
const container = require('markdown-it-container')
|
const container = require('markdown-it-container')
|
||||||
|
|
||||||
let ogprefix = 'og: http://ogp.me/ns#'
|
const ogprefix = 'og: http://ogp.me/ns#'
|
||||||
let title = 'Strapi Documentation'
|
const title = 'Strapi Documentation'
|
||||||
let description = 'API creation made simple, secure and fast.'
|
const description = 'API creation made simple, secure and fast.'
|
||||||
let color = '#2F80ED'
|
const color = '#2F80ED'
|
||||||
let author = 'Strapi'
|
const author = 'Strapi'
|
||||||
let url = 'https://strapi.io/documentation/'
|
const url = 'https://strapi.io/documentation/'
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
head: [
|
head: [
|
||||||
@ -47,15 +46,20 @@ module.exports = {
|
|||||||
['Version 1.x.x', '/1.x.x/'],
|
['Version 1.x.x', '/1.x.x/'],
|
||||||
],
|
],
|
||||||
repo: 'strapi/strapi',
|
repo: 'strapi/strapi',
|
||||||
|
website: 'https://strapi.io',
|
||||||
docsDir: 'docs',
|
docsDir: 'docs',
|
||||||
editLinks: true,
|
editLinks: true,
|
||||||
editLinkText: 'Improve this page',
|
editLinkText: 'Improve this page',
|
||||||
serviceWorker: true,
|
serviceWorker: true,
|
||||||
|
hiddenLinks: [
|
||||||
|
'/3.x.x/cli/CLI.html',
|
||||||
|
'/3.x.x/api-reference/reference.html',
|
||||||
|
],
|
||||||
sidebar: {
|
sidebar: {
|
||||||
'/3.x.x/': [
|
'/3.x.x/': [
|
||||||
{
|
{
|
||||||
collapsable: false,
|
collapsable: false,
|
||||||
title: 'Getting started',
|
title: '🚀 Getting started',
|
||||||
children: [
|
children: [
|
||||||
'/3.x.x/getting-started/installation',
|
'/3.x.x/getting-started/installation',
|
||||||
'/3.x.x/getting-started/quick-start',
|
'/3.x.x/getting-started/quick-start',
|
||||||
@ -63,39 +67,30 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
collapsable: false,
|
collapsable: true,
|
||||||
title: 'Guides',
|
title: '💡 Guides',
|
||||||
children: [
|
children: [
|
||||||
'/3.x.x/guides/authentication.md',
|
'/3.x.x/guides/authentication',
|
||||||
'/3.x.x/configurations/configurations.md',
|
|
||||||
'/3.x.x/guides/controllers.md',
|
|
||||||
'/3.x.x/guides/deployment.md',
|
|
||||||
'/3.x.x/guides/email.md',
|
|
||||||
'/3.x.x/guides/upload.md',
|
|
||||||
'/3.x.x/guides/filters.md',
|
|
||||||
'/3.x.x/guides/graphql.md',
|
|
||||||
'/3.x.x/guides/i18n.md',
|
|
||||||
'/3.x.x/guides/models.md',
|
|
||||||
'/3.x.x/guides/policies.md',
|
|
||||||
'/3.x.x/guides/public-assets.md',
|
|
||||||
'/3.x.x/guides/requests.md',
|
|
||||||
'/3.x.x/guides/responses.md',
|
|
||||||
'/3.x.x/guides/routing.md',
|
|
||||||
'/3.x.x/guides/services.md',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
collapsable: false,
|
|
||||||
title: 'Globals',
|
|
||||||
children: [
|
|
||||||
'/3.x.x/api-reference/reference',
|
|
||||||
'/3.x.x/cli/CLI',
|
|
||||||
'/3.x.x/configurations/configurations',
|
'/3.x.x/configurations/configurations',
|
||||||
|
'/3.x.x/guides/controllers',
|
||||||
|
'/3.x.x/guides/deployment',
|
||||||
|
'/3.x.x/guides/email',
|
||||||
|
'/3.x.x/guides/upload',
|
||||||
|
'/3.x.x/guides/filters',
|
||||||
|
'/3.x.x/guides/graphql',
|
||||||
|
'/3.x.x/guides/i18n',
|
||||||
|
'/3.x.x/guides/models',
|
||||||
|
'/3.x.x/guides/policies',
|
||||||
|
'/3.x.x/guides/public-assets',
|
||||||
|
'/3.x.x/guides/requests',
|
||||||
|
'/3.x.x/guides/responses',
|
||||||
|
'/3.x.x/guides/routing',
|
||||||
|
'/3.x.x/guides/services',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
collapsable: false,
|
collapsable: true,
|
||||||
title: 'Advanced',
|
title: '⚙️️ Advanced',
|
||||||
children: [
|
children: [
|
||||||
'/3.x.x/advanced/customize-admin',
|
'/3.x.x/advanced/customize-admin',
|
||||||
'/3.x.x/advanced/hooks',
|
'/3.x.x/advanced/hooks',
|
||||||
@ -104,9 +99,36 @@ module.exports = {
|
|||||||
'/3.x.x/advanced/usage-tracking',
|
'/3.x.x/advanced/usage-tracking',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
collapsable: true,
|
||||||
|
title: '🔌 Plugin Development',
|
||||||
|
children: [
|
||||||
|
'/3.x.x/plugin-development/quick-start',
|
||||||
|
'/3.x.x/plugin-development/plugin-architecture',
|
||||||
|
'/3.x.x/plugin-development/backend-development',
|
||||||
|
'/3.x.x/plugin-development/frontend-development',
|
||||||
|
'/3.x.x/plugin-development/frontend-use-cases',
|
||||||
|
'/3.x.x/plugin-development/utils',
|
||||||
|
// '/3.x.x/plugin-development/ui-components', TODO: Add this file
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
collapsable: true,
|
||||||
|
title: '💻 Command Line Interface',
|
||||||
|
children: [
|
||||||
|
'/3.x.x/cli/CLI',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
collapsable: true,
|
||||||
|
title: '🏗 API Reference',
|
||||||
|
children: [
|
||||||
|
'/3.x.x/api-reference/reference',
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
collapsable: false,
|
collapsable: false,
|
||||||
title: 'Resources',
|
title: '📚 Resources',
|
||||||
children: [
|
children: [
|
||||||
['https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md', 'Contributing guide'],
|
['https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md', 'Contributing guide'],
|
||||||
['https://github.com/strapi/strapi/wiki', 'Migration guides'],
|
['https://github.com/strapi/strapi/wiki', 'Migration guides'],
|
||||||
|
@ -5,14 +5,7 @@
|
|||||||
@touchend="onTouchEnd">
|
@touchend="onTouchEnd">
|
||||||
<Navbar v-if="shouldShowNavbar" @toggle-sidebar="toggleSidebar"/>
|
<Navbar v-if="shouldShowNavbar" @toggle-sidebar="toggleSidebar"/>
|
||||||
<div class="sidebar-mask" @click="toggleSidebar(false)"></div>
|
<div class="sidebar-mask" @click="toggleSidebar(false)"></div>
|
||||||
<Sidebar :items="sidebarItems" @toggle-sidebar="toggleSidebar">
|
<Sidebar :items="sidebarItems" @toggle-sidebar="toggleSidebar" />
|
||||||
<div slot="top">
|
|
||||||
<select @input="changeVersion($event.target.value)" class="version-selector">
|
|
||||||
<option v-for="version in versions" :value="version.path" :selected="!!~$page.path.indexOf(version.path)">{{version.name}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<slot name="sidebar-bottom" slot="bottom"/>
|
|
||||||
</Sidebar>
|
|
||||||
<div class="custom-layout" v-if="$page.frontmatter.layout">
|
<div class="custom-layout" v-if="$page.frontmatter.layout">
|
||||||
<component :is="$page.frontmatter.layout"/>
|
<component :is="$page.frontmatter.layout"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -9,11 +9,19 @@
|
|||||||
<NavLink v-else :item="item"/>
|
<NavLink v-else :item="item"/>
|
||||||
</div>
|
</div>
|
||||||
<!-- repo link -->
|
<!-- repo link -->
|
||||||
<a v-if="repoLink"
|
<a
|
||||||
:href="repoLink"
|
:href="websiteLink"
|
||||||
class="repo-link"
|
class="repo-link"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer">
|
rel="noopener noreferrer">
|
||||||
|
Website
|
||||||
|
<OutboundLink/>
|
||||||
|
</a>
|
||||||
|
<a v-if="repoLink"
|
||||||
|
:href="repoLink"
|
||||||
|
class="repo-link"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer">
|
||||||
{{ repoLabel }}
|
{{ repoLabel }}
|
||||||
<OutboundLink/>
|
<OutboundLink/>
|
||||||
</a>
|
</a>
|
||||||
@ -92,6 +100,22 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 'Source'
|
return 'Source'
|
||||||
|
},
|
||||||
|
websiteLink () {
|
||||||
|
const { website } = this.$site.themeConfig
|
||||||
|
if (website) {
|
||||||
|
return /^https?:/.test(website)
|
||||||
|
? website
|
||||||
|
: `https://${website}`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
slackLink () {
|
||||||
|
const { slack } = this.$site.themeConfig
|
||||||
|
if (slack) {
|
||||||
|
return /^https?:/.test(slack)
|
||||||
|
? slack
|
||||||
|
: `https://${slack}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
{{ $siteTitle }}
|
{{ $siteTitle }}
|
||||||
</span>
|
</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<select @input="changeVersion($event.target.value)" class="version-selector">
|
||||||
|
<option v-for="version in versions" :value="version.path" :selected="!!~$page.path.indexOf(version.path)">{{version.name}}</option>
|
||||||
|
</select>
|
||||||
<div class="links">
|
<div class="links">
|
||||||
<AlgoliaSearchBox v-if="isAlgoliaSearch" :options="algolia"/>
|
<AlgoliaSearchBox v-if="isAlgoliaSearch" :options="algolia"/>
|
||||||
<SearchBox v-else-if="$site.themeConfig.search !== false"/>
|
<SearchBox v-else-if="$site.themeConfig.search !== false"/>
|
||||||
@ -28,12 +31,24 @@ import NavLinks from './NavLinks.vue'
|
|||||||
export default {
|
export default {
|
||||||
components: { SidebarButton, NavLinks, SearchBox, AlgoliaSearchBox },
|
components: { SidebarButton, NavLinks, SearchBox, AlgoliaSearchBox },
|
||||||
computed: {
|
computed: {
|
||||||
|
versions() {
|
||||||
|
const { themeConfig } = this.$site
|
||||||
|
return themeConfig.versions.map(version => ({
|
||||||
|
name: version[0],
|
||||||
|
path: version[1],
|
||||||
|
}))
|
||||||
|
},
|
||||||
algolia () {
|
algolia () {
|
||||||
return this.$themeLocaleConfig.algolia || this.$site.themeConfig.algolia || {}
|
return this.$themeLocaleConfig.algolia || this.$site.themeConfig.algolia || {}
|
||||||
},
|
},
|
||||||
isAlgoliaSearch () {
|
isAlgoliaSearch () {
|
||||||
return this.algolia && this.algolia.apiKey && this.algolia.indexName
|
return this.algolia && this.algolia.apiKey && this.algolia.indexName
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeVersion(to) {
|
||||||
|
this.$router.push(to)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
@blur="focused = false"
|
@blur="focused = false"
|
||||||
@keyup.enter="go(focusIndex)"
|
@keyup.enter="go(focusIndex)"
|
||||||
@keyup.up="onUp"
|
@keyup.up="onUp"
|
||||||
@keyup.down="onDown">
|
@keyup.down="onDown"
|
||||||
|
placeholder="Search"
|
||||||
|
>
|
||||||
<ul class="suggestions"
|
<ul class="suggestions"
|
||||||
v-if="showSuggestions"
|
v-if="showSuggestions"
|
||||||
:class="{ 'align-right': alignRight }"
|
:class="{ 'align-right': alignRight }"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<DropdownTransition>
|
<DropdownTransition>
|
||||||
<ul class="sidebar-group-items" ref="items" v-if="open || !collapsable">
|
<ul class="sidebar-group-items" ref="items" v-if="open || !collapsable">
|
||||||
<li v-for="child in item.children">
|
<li v-for="child in item.children">
|
||||||
<SidebarLink :item="child"/>
|
<SidebarLink :item="child" :open="open" :collapsable="collapsable"/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</DropdownTransition>
|
</DropdownTransition>
|
||||||
|
@ -5,8 +5,8 @@ import AppLink from './AppLink'
|
|||||||
export default {
|
export default {
|
||||||
functional: true,
|
functional: true,
|
||||||
components: {AppLink},
|
components: {AppLink},
|
||||||
props: ['item'],
|
props: ['item', 'open', 'collapsable'],
|
||||||
render (h, { parent: { $page, $site, $route }, props: { item }}) {
|
render (h, { parent: { $page, $site, $route }, props: { item, open, collapsable }}) {
|
||||||
// use custom active class matching logic
|
// use custom active class matching logic
|
||||||
// due to edge case of paths ending with / + hash
|
// due to edge case of paths ending with / + hash
|
||||||
const selfActive = isActive($route, item.path)
|
const selfActive = isActive($route, item.path)
|
||||||
@ -15,7 +15,8 @@ export default {
|
|||||||
const active = item.type === 'auto'
|
const active = item.type === 'auto'
|
||||||
? selfActive || item.children.some(c => isActive($route, item.basePath + '#' + c.slug))
|
? selfActive || item.children.some(c => isActive($route, item.basePath + '#' + c.slug))
|
||||||
: selfActive
|
: selfActive
|
||||||
const link = renderLink(h, item.path, item.title || item.path, active)
|
const hidden = $site.themeConfig.hiddenLinks.includes(item.path);
|
||||||
|
const link = renderLink(h, item.path, item.title || item.path, active, hidden)
|
||||||
const configDepth = $page.frontmatter.sidebarDepth != null
|
const configDepth = $page.frontmatter.sidebarDepth != null
|
||||||
? $page.frontmatter.sidebarDepth
|
? $page.frontmatter.sidebarDepth
|
||||||
: $site.themeConfig.sidebarDepth
|
: $site.themeConfig.sidebarDepth
|
||||||
@ -25,13 +26,16 @@ export default {
|
|||||||
} else if (active && item.headers && !hashRE.test(item.path)) {
|
} else if (active && item.headers && !hashRE.test(item.path)) {
|
||||||
const children = groupHeaders(item.headers)
|
const children = groupHeaders(item.headers)
|
||||||
return [link, renderChildren(h, children, item.path, $route, maxDepth)]
|
return [link, renderChildren(h, children, item.path, $route, maxDepth)]
|
||||||
|
} else if (collapsable && open && hidden && !active && item.headers && !hashRE.test(item.path)) {
|
||||||
|
const children = groupHeaders(item.headers)
|
||||||
|
return [link, renderChildren(h, children, item.path, $route, maxDepth)]
|
||||||
} else {
|
} else {
|
||||||
return link
|
return link
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderLink (h, to, text, active) {
|
function renderLink (h, to, text, active, hidden) {
|
||||||
if (~to.indexOf('http')) return h('a',
|
if (~to.indexOf('http')) return h('a',
|
||||||
{
|
{
|
||||||
attrs: {
|
attrs: {
|
||||||
@ -48,6 +52,7 @@ function renderLink (h, to, text, active) {
|
|||||||
},
|
},
|
||||||
class: {
|
class: {
|
||||||
active,
|
active,
|
||||||
|
hidden,
|
||||||
'sidebar-link': true
|
'sidebar-link': true
|
||||||
}
|
}
|
||||||
}, text)
|
}, text)
|
||||||
@ -58,7 +63,7 @@ function renderChildren (h, children, path, route, maxDepth, depth = 1) {
|
|||||||
return h('ul', { class: 'sidebar-sub-headers' }, children.map(c => {
|
return h('ul', { class: 'sidebar-sub-headers' }, children.map(c => {
|
||||||
const active = isActive(route, path + '#' + c.slug)
|
const active = isActive(route, path + '#' + c.slug)
|
||||||
return h('li', { class: 'sidebar-sub-header' }, [
|
return h('li', { class: 'sidebar-sub-header' }, [
|
||||||
renderLink(h, '#' + c.slug, c.title, active),
|
renderLink(h, path + '#' + c.slug, c.title, active),
|
||||||
renderChildren(h, c.children, path, route, maxDepth, depth + 1)
|
renderChildren(h, c.children, path, route, maxDepth, depth + 1)
|
||||||
])
|
])
|
||||||
}))
|
}))
|
||||||
@ -87,6 +92,8 @@ a.sidebar-link
|
|||||||
font-weight 600
|
font-weight 600
|
||||||
color $accentColor
|
color $accentColor
|
||||||
border-left-color $accentColor
|
border-left-color $accentColor
|
||||||
|
&.hidden
|
||||||
|
display: none
|
||||||
.sidebar-group &
|
.sidebar-group &
|
||||||
padding-left 2rem
|
padding-left 2rem
|
||||||
.sidebar-sub-headers &
|
.sidebar-sub-headers &
|
||||||
|
@ -8,7 +8,7 @@ $arrowBgColor = #ccc
|
|||||||
// layout
|
// layout
|
||||||
$navbarHeight = 3.6rem
|
$navbarHeight = 3.6rem
|
||||||
$sidebarWidth = 20rem
|
$sidebarWidth = 20rem
|
||||||
$contentWidth = 740px
|
$contentWidth = 800px
|
||||||
|
|
||||||
// responsive breakpoints
|
// responsive breakpoints
|
||||||
$MQNarrow = 959px
|
$MQNarrow = 959px
|
||||||
|
@ -27,9 +27,8 @@ a img + svg
|
|||||||
display none !important
|
display none !important
|
||||||
|
|
||||||
.version-selector
|
.version-selector
|
||||||
margin 1em 1em 0 1.5em
|
margin-left 1.5rem
|
||||||
color lighten($textColor, 25%)
|
color lighten($textColor, 25%)
|
||||||
display block
|
|
||||||
border 1px solid darken($borderColor, 10%)
|
border 1px solid darken($borderColor, 10%)
|
||||||
font-size .9rem
|
font-size .9rem
|
||||||
line-height 2rem
|
line-height 2rem
|
||||||
|
BIN
docs/3.x.x/assets/getting-started_add_entry-.png
Normal file
After Width: | Height: | Size: 260 KiB |
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 601 KiB |
Before Width: | Height: | Size: 288 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 462 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 440 KiB |
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 432 KiB |
BIN
docs/3.x.x/assets/getting-started_no_entry_.png
Normal file
After Width: | Height: | Size: 435 KiB |
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 455 KiB |
BIN
docs/3.x.x/assets/getting-started_with_entry_.png
Normal file
After Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 254 KiB After Width: | Height: | Size: 64 KiB |
@ -1,6 +1,8 @@
|
|||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
Installation is very easy and only takes a few seconds.
|
### 👋 Welcome onboard!
|
||||||
|
|
||||||
|
You recently discovered Strapi and look forward to give it a try? Let's start with the installation!
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
@ -8,10 +10,11 @@ Please make sure your computer/server meets the following requirements:
|
|||||||
- [Node.js](https://nodejs.org) >= 10.x: Node.js is a server platform which runs JavaScript. Installation guide [here](https://nodejs.org/en/download/).
|
- [Node.js](https://nodejs.org) >= 10.x: Node.js is a server platform which runs JavaScript. Installation guide [here](https://nodejs.org/en/download/).
|
||||||
- [NPM](https://www.npmjs.com/) >= 6.x: NPM is the package manager for Javascript. Installation guide [here](https://nodejs.org/en/download/).
|
- [NPM](https://www.npmjs.com/) >= 6.x: NPM is the package manager for Javascript. Installation guide [here](https://nodejs.org/en/download/).
|
||||||
*(Make sure the database that you are using meets the requirement.)*
|
*(Make sure the database that you are using meets the requirement.)*
|
||||||
- [MongoDB](https://www.mongodb.com/) >= 3.x: MongoDB is a powerful document store. Installation guide [here](https://www.mongodb.com/download-center?j#community).
|
- The database of your choice:
|
||||||
- [MySQL](https://www.mysql.com/) >= 5.6: MySQL is an open-source relational database management system. Installation guide [here](https://dev.mysql.com/downloads/).
|
- [MongoDB](https://www.mongodb.com/) >= 3.x: MongoDB is a powerful document store. Installation guide [here](https://www.mongodb.com/download-center?j#community).
|
||||||
- [MariaDB](https://mariadb.org/) >= 10.1: MarialDB is a fork of MySQL and is guaranteed to stay open source. Installation guide [here](https://mariadb.org/download/).
|
- [MySQL](https://www.mysql.com/) >= 5.6: MySQL is an open-source relational database management system. Installation guide [here](https://dev.mysql.com/downloads/).
|
||||||
- [PostgreSQL](https://www.postgresql.org/) >= 10: PostgreSQL is an open-source object-relational database management system. Installation guide [here](https://www.postgresql.org/download/).
|
- [MariaDB](https://mariadb.org/) >= 10.1: MarialDB is a fork of MySQL and is guaranteed to stay open source. Installation guide [here](https://mariadb.org/download/).
|
||||||
|
- [PostgreSQL](https://www.postgresql.org/) >= 10: PostgreSQL is an open-source object-relational database management system. Installation guide [here](https://www.postgresql.org/download/).
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
@ -27,7 +30,7 @@ If you encounter npm permissions issues, [change the permissions to npm default
|
|||||||
|
|
||||||
It takes about 20 seconds with a good Internet connection. You can take a coffee ☕️ if you have a slow one.
|
It takes about 20 seconds with a good Internet connection. You can take a coffee ☕️ if you have a slow one.
|
||||||
|
|
||||||
Having troubles during the installation? Check if someone already had the same issue https://github.com/strapi/strapi/issues. If not, you can [post one](https://github.com/strapi/strapi/issues/new), or ask for help https://strapi.io/support.
|
Having troubles during the installation? Check if someone already had the [same issue](https://github.com/strapi/strapi/issues). If not, please [post one](https://github.com/strapi/strapi/issues/new).
|
||||||
|
|
||||||
## Check installation
|
## Check installation
|
||||||
|
|
||||||
@ -43,4 +46,4 @@ Strapi is installed globally on your computer. Type `strapi` in your terminal yo
|
|||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
Congrats! Now that Strapi is installed you can [create your first API](quick-start.md).
|
👏 Congrats, you are all set! Now that Strapi is installed you can [create your first project](quick-start.md).
|
||||||
|
@ -3,22 +3,21 @@
|
|||||||
This section explains how to handle Strapi for the first time, ([check out our tutorial video](https://www.youtube.com/watch?v=yMl5IcFHA74)).
|
This section explains how to handle Strapi for the first time, ([check out our tutorial video](https://www.youtube.com/watch?v=yMl5IcFHA74)).
|
||||||
|
|
||||||
**Table of contents:**
|
**Table of contents:**
|
||||||
- [Quick start](#quick-start)
|
- [1. Create your first project](#_1-create-a-project)
|
||||||
- [Create your first project](#create-your-first-project)
|
- [2. Create your first user](#_2-register-the-first-user)
|
||||||
- [Create your first user](#create-your-first-user)
|
- [3. Create your first Content Type](#_3-create-a-content-type)
|
||||||
- [Create your first API](#create-your-first-api)
|
- [Files structure](#files-structure)
|
||||||
- [Files structure](#files-structure)
|
- [4. Manage your data](#_4-add-content)
|
||||||
- [Manage your data](#manage-your-data)
|
- [5. Consume your API](#_5-consume-the-api)
|
||||||
- [Consume your API](#consume-your-api)
|
- [List entries (GET)](#list-entries-get)
|
||||||
- [List entries (GET)](#list-entries-get)
|
- [Get a specific entry (GET)](#get-a-specific-entry-get)
|
||||||
- [Get a specific entry (GET)](#get-a-specific-entry-get)
|
- [Create data (POST)](#create-data-post)
|
||||||
- [Create data (POST)](#create-data-post)
|
- [Update data (PUT)](#update-data-put)
|
||||||
- [Update data (PUT)](#update-data-put)
|
- [Delete data (DELETE)](#delete-data-delete)
|
||||||
- [Delete data (DELETE)](#delete-data-delete)
|
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
## Create your first project
|
## 1. Create a project
|
||||||
|
|
||||||
Creating your first project with Strapi is easy:
|
Creating your first project with Strapi is easy:
|
||||||
|
|
||||||
@ -34,6 +33,10 @@ strapi new my-project
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
::: note
|
||||||
|
The CLI will ask you to choose your database: select MongoDB, Postgres or MySQL. Then, fill the database information in. The default values should work if you correctly installed the database system on your machine.
|
||||||
|
:::
|
||||||
|
|
||||||
This action creates a new folder named `my-project` with the entire [files structure](../concepts/concepts.md#files-structure) of a Strapi application.
|
This action creates a new folder named `my-project` with the entire [files structure](../concepts/concepts.md#files-structure) of a Strapi application.
|
||||||
|
|
||||||
**#3 — Go to your project and launch the server:**
|
**#3 — Go to your project and launch the server:**
|
||||||
@ -47,44 +50,42 @@ strapi start
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Now that your app is running let's see how to [create your first user](#create-your-first-user).
|
Now that your app is running let's see how to [create your first user](#_2-register-the-first-user).
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
## Create your first user
|
## 2. Register the first user
|
||||||
|
|
||||||
In order to use the admin panel and to consume your API you first need to register your first user. This process only happens once if you don't have any user table created and is made to create the `admin user` that has all the permissions granted for your API.
|
In order to use the admin panel and to consume your API you first need to register your first user. This process only happens once and is made to create the `admin user` who has all the permissions granted.
|
||||||
|
|
||||||
If you're using MongoDB for your database you don't have to create your table manually (it's already handled by Strapi) otherwise you'll have to create your user table first.
|
To create your first user, start your server (`strapi start`) and go to [http://localhost:1337/admin](http://localhost:1337/admin).
|
||||||
|
|
||||||
To create your first user, start your server (`strapi start`) and go to : http://localhost:1337/admin.
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
Now that your first user is registered let's see how to [create your first api](#create-your-first-api).
|
Now that your first user is registered let's see how to [create your first Content Type](#_3-create-a-content-type).
|
||||||
|
|
||||||
***
|
***
|
||||||
## Create your first API
|
|
||||||
|
|
||||||
To create your first API, start your server (`strapi start`) and go to : http://localhost:1337/admin.
|
## 3. Create a Content Type
|
||||||
|
|
||||||
At this point, your application is empty. To create your first API is to use the **Content Type Builder** plugin: a powerful UI to help you create an API in a few clicks. Let's take the example of an e-commerce API, which manages products.
|
At this point, your project is empty. To create your first Content Type, you are going to use the **Content Type Builder** plugin: a powerful UI to help defining your Content Type's structure within a few clicks. Let's take the example of blog, which manages posts.
|
||||||
|
|
||||||
**#1 —** Go to the **Content Type Builder** plugin.
|
**#1 —** Go to the **Content Type Builder** plugin.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**#2 —** Create a Content Type named `Product` and submit the form.
|
**#2 —** Create a Content Type named `Post` and submit the form.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**#3 —** Add three fields in this Content Type.
|
**#3 —** Add three fields in this Content Type.
|
||||||
|
|
||||||
- A `string` field named `name`.
|
- A `string` field named `title`.
|
||||||
- A `text` field named `description`.
|
- A `text` field named `content` (tick the `Display as WYSIWYG` in the `Advanced Settings` tab).
|
||||||
- A `number` field named `price` (with `float` as number format).
|
- A `media` field named `cover`.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**#4 —** Save. That's it!
|
**#4 —** Save. That's it!
|
||||||
|
|
||||||
@ -95,22 +96,22 @@ See the [CLI documentation](../cli/CLI.md#strapi-generateapi) for more informati
|
|||||||
|
|
||||||
### Files structure
|
### Files structure
|
||||||
|
|
||||||
A new directory has been created in the `./api` folder of your application which contains all the needed stuff for your `Product` Content Type: routes, controllers, services and models. Take a look at the [API structure documentation](../concepts/concepts.md#files-structure) for more informations.
|
A new directory has been created in the `./api` folder of your application which contains all the needed stuff for your `Post` Content Type: routes, controllers, services and models. Take a look at the [API structure documentation](../concepts/concepts.md#files-structure) for more informations.
|
||||||
|
|
||||||
|
|
||||||
**Well done, you created your first API using Strapi!**
|
**Well done, you created your first Content Type using Strapi!**
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
## Manage your data
|
## 4. Add content
|
||||||
|
|
||||||
After creating [your first Content Type](#create-your-first-api), it would be great to be able to create, edit or delete entries.
|
After creating [your first Content Type](#_3-create-a-content-type), you probably want to create, edit or delete entries. No worries, everything is ready for you:
|
||||||
|
|
||||||
**#1 —** Go to the [**Product list**](http://localhost:1337/admin/plugins/content-manager/product/) by clicking on the link in the left menu (generated by the **Content Manager** plugin).
|
**#1 —** Go to the [**Post list**](http://localhost:1337/admin/plugins/content-manager/post/) by clicking on the link in the left menu (generated by the **Content Manager** plugin).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**#2 —** Click on the button `Add New Product` and fill the form.
|
**#2 —** Click on the button `Add New Post` and fill the form.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -120,125 +121,161 @@ After creating [your first Content Type](#create-your-first-api), it would be gr
|
|||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
## Consume your API
|
## 5. Consume the API
|
||||||
|
|
||||||
Your API is now ready and [contains data](#manage-your-data). At this point, you'll probably want to use this data in mobile or desktop applications.
|
Your API is now ready and [contains data](#_4-add-content). At this point, you'll probably want to use this data in mobile or desktop applications.
|
||||||
In order to do so, you'll need to allow access to other users (identified as 'Guest').
|
In order to do so, you'll need to allow access to other users (identified as 'Public').
|
||||||
|
|
||||||
**1 -** Go to the [**Auth & Permissions View**](http://localhost:1337/admin/plugins/users-permissions/roles) by clicking on **Auth & Permissions** link in the left menu and click on the **Guest Role** item.
|
**1 -** Go to the [**Auth & Permissions View**](http://localhost:1337/admin/plugins/users-permissions/roles) by clicking on **Auth & Permissions** link in the left menu.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**2 -** Manage your APIs permissions in the **Permissions** section of the [**Edit Guest Role view**](http://localhost:1337/admin/plugins/users-permissions/roles/edit/1) by enabling or disabling specific actions.
|
**2 -** Click on the `Public` role, enable the actions related to your new Content Type and save:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
::: note
|
||||||
|
You should now be able to get the list of posts from the API: [http://localhost:1337/posts](http://localhost:1337/posts).
|
||||||
|
:::
|
||||||
|
|
||||||
### List entries (GET)
|
### List entries (GET)
|
||||||
|
|
||||||
To retrieve the list of products, use the `GET /products` route.
|
To retrieve the list of posts, use the `GET /posts` 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/products?_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 posts by price is as easy as `GET http://localhost:1337/posts?_sort=price:asc`. For more informations, read the [filters documentation](../guides/filters.md).
|
||||||
|
|
||||||
Here is an example using jQuery.
|
Here is an example using Axios:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'GET',
|
|
||||||
url: 'http://localhost:1337/products?_sort=price:asc', // Order by price.
|
// Request API.
|
||||||
done: function(products) {
|
axios
|
||||||
console.log('Well done, here is the list of products: ', products);
|
.get('http://localhost:1337/posts', {
|
||||||
},
|
params: {
|
||||||
fail: function(error) {
|
_sort: 'createdAt:desc' // Generates http://localhost:1337/posts?_sort=createdAt:desc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
// Handle success.
|
||||||
|
console.log('Well done, here is the list of posts: ', response.data);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Get a specific entry (GET)
|
### Get a specific entry (GET)
|
||||||
|
|
||||||
If you want to get a specific entry, add the `id` of the wanted product at the end of the url.
|
If you want to get a specific entry, add the `id` of the wanted post at the end of the url.
|
||||||
|
|
||||||
|
Examble with Axios:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'GET',
|
|
||||||
url: 'http://localhost:1337/products/123', // Where `123` is the `id` of the product.
|
const postId = 'YOUR_POST_ID_HERE'; // Replace with one of your posts id.
|
||||||
done: function(product) {
|
|
||||||
console.log('Well done, here is the product having the `id` 123: ', product);
|
// Request API.
|
||||||
},
|
axios
|
||||||
fail: function(error) {
|
.get(`http://localhost:1337/posts/${postId}`)
|
||||||
|
.then(response => {
|
||||||
|
// Handle success.
|
||||||
|
console.log('Well done, here is the post: ', response.data);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create data (POST)
|
### Create data (POST)
|
||||||
|
|
||||||
Use the `POST` route to create a new entry.
|
Use the `POST` route to create a new entry.
|
||||||
|
|
||||||
jQuery example:
|
Examble with Axios:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'POST',
|
|
||||||
url: 'http://localhost:1337/products',
|
// Request API.
|
||||||
data: {
|
axios
|
||||||
name: 'Cheese cake',
|
.post(`http://localhost:1337/posts/`, {
|
||||||
description: 'Chocolate cheese cake with ice cream',
|
title: 'My new post'
|
||||||
price: 5
|
})
|
||||||
},
|
.then(response => {
|
||||||
done: function(product) {
|
// Handle success.
|
||||||
console.log('Congrats, your product has been successfully created: ', product); // Remember the product `id` for the next steps.
|
console.log(
|
||||||
},
|
'Well done, your post has been successfully created: ',
|
||||||
fail: function(error) {
|
response.data
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Update data (PUT)
|
### Update data (PUT)
|
||||||
|
|
||||||
Use the `PUT` route to update an existing entry.
|
Use the `PUT` route to update an existing entry.
|
||||||
|
|
||||||
jQuery example:
|
Examble with Axios:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'PUT',
|
|
||||||
url: 'http://localhost:1337/products/123', // Where `123` is the `id` of the product.
|
const postId = 'YOUR_POST_ID_HERE'; // Replace with one of your posts id.
|
||||||
data: {
|
|
||||||
description: 'This is the new description'
|
// Request API.
|
||||||
},
|
axios
|
||||||
done: function(product) {
|
.put(`http://localhost:1337/posts/${postId}`, {
|
||||||
console.log('Congrats, your product has been successfully updated: ', product.description);
|
title: 'Updated title'
|
||||||
},
|
})
|
||||||
fail: function(error) {
|
.then(response => {
|
||||||
|
// Handle success.
|
||||||
|
console.log(
|
||||||
|
'Well done, your post has been successfully updated: ',
|
||||||
|
response.data
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Delete data (DELETE)
|
### Delete data (DELETE)
|
||||||
|
|
||||||
Use the `DELETE` route to delete an existing entry.
|
Use the `DELETE` route to delete an existing entry.
|
||||||
|
|
||||||
jQuery example:
|
Examble with Axios:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'DELETE',
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
fail: function(error) {
|
|
||||||
console.log('An error occurred:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
|
const postId = 'YOUR_POST_ID_HERE'; // Replace with one of your posts id.
|
||||||
|
|
||||||
|
// Request API.
|
||||||
|
axios
|
||||||
|
.delete(`http://localhost:1337/posts/${postId}`)
|
||||||
|
.then(response => {
|
||||||
|
// Handle success.
|
||||||
|
console.log(
|
||||||
|
'Well done, your post has been successfully updated: ',
|
||||||
|
response.data
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
|
console.log('An error occurred:', error);
|
||||||
|
});
|
||||||
|
```
|
||||||
***
|
***
|
||||||
|
|
||||||
Congratulations! You successfully finished the Getting Started guide! Read the [concepts](../concepts/concepts.md) to understand more advanced concepts.
|
#### 👏 Congratulations!
|
||||||
|
|
||||||
|
You successfully finished the Getting Started guide! Read the [concepts section](../concepts/concepts.md) to understand more deeply how to use and customize Strapi.
|
||||||
|
|
||||||
Also, feel free to join the community thanks to the different channels listed in the [community page](http://strapi.io/community): team members, contributors and developers will be happy to help you.
|
Also, feel free to join the community thanks to the different channels listed in the [community page](http://strapi.io/community): team members, contributors and developers will be happy to help you.
|
||||||
|
@ -4,33 +4,35 @@
|
|||||||
This feature requires the Users & Permissions plugin (installed by default).
|
This feature requires the Users & Permissions plugin (installed by default).
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Register a new user
|
## Registration
|
||||||
|
|
||||||
This route lets you create new users.
|
This route lets you create new users.
|
||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'POST',
|
|
||||||
url: 'http://localhost:1337/auth/local/register',
|
// Request API.
|
||||||
data: {
|
axios
|
||||||
|
.post('http://localhost:1337/auth/local/register', {
|
||||||
username: 'Strapi user',
|
username: 'Strapi user',
|
||||||
email: 'user@strapi.io',
|
email: 'user@strapi.io',
|
||||||
password: 'strapiPassword'
|
password: 'strapiPassword'
|
||||||
},
|
})
|
||||||
done: function(auth) {
|
.then(response => {
|
||||||
|
// Handle success.
|
||||||
console.log('Well done!');
|
console.log('Well done!');
|
||||||
console.log('User profile', auth.user);
|
console.log('User profile', response.data.user);
|
||||||
console.log('User token', auth.jwt);
|
console.log('User token', response.data.jwt);
|
||||||
},
|
})
|
||||||
fail: function(error) {
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Login.
|
## Login
|
||||||
|
|
||||||
This route lets you login your users by getting an authentication token.
|
This route lets you login your users by getting an authentication token.
|
||||||
|
|
||||||
@ -39,22 +41,24 @@ This route lets you login your users by getting an authentication token.
|
|||||||
- The `identifier` param can either be an email or a username.
|
- The `identifier` param can either be an email or a username.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'POST',
|
|
||||||
url: 'http://localhost:1337/auth/local',
|
// Request API.
|
||||||
data: {
|
axios
|
||||||
identifier: 'user@strapi.io',
|
.post('http://localhost:1337/auth/local', {
|
||||||
password: 'strapiPassword'
|
identifier: 'user@strapi.io',
|
||||||
},
|
password: 'strapiPassword'
|
||||||
done: function(auth) {
|
})
|
||||||
|
.then(response => {
|
||||||
|
// Handle success.
|
||||||
console.log('Well done!');
|
console.log('Well done!');
|
||||||
console.log('User profile', auth.user);
|
console.log('User profile', response.data.user);
|
||||||
console.log('User token', auth.jwt);
|
console.log('User token', response.data.jwt);
|
||||||
},
|
})
|
||||||
fail: function(error) {
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Providers
|
## Providers
|
||||||
@ -81,14 +85,14 @@ After his approval, he will be redirected to `/auth/:provider/callback`. The `jw
|
|||||||
|
|
||||||
Response payload:
|
Response payload:
|
||||||
|
|
||||||
```js
|
```json
|
||||||
{
|
{
|
||||||
"user": {},
|
"user": {},
|
||||||
"jwt": ""
|
"jwt": ""
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Use your token to be identified as a user.
|
## Token usage
|
||||||
|
|
||||||
By default, each API request is identified as `guest` role (see permissions of `guest`'s role in your admin dashboard). To make a request as a user, you have to set the `Authorization` token in your request headers. You receive a 401 error if you are not authorized to make this request or if your authorization header is not correct.
|
By default, each API request is identified as `guest` role (see permissions of `guest`'s role in your admin dashboard). To make a request as a user, you have to set the `Authorization` token in your request headers. You receive a 401 error if you are not authorized to make this request or if your authorization header is not correct.
|
||||||
|
|
||||||
@ -97,22 +101,28 @@ By default, each API request is identified as `guest` role (see permissions of `
|
|||||||
- The `token` variable is the `data.jwt` received when login in or registering.
|
- The `token` variable is the `data.jwt` received when login in or registering.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'GET',
|
|
||||||
url: 'http://localhost:1337/articles',
|
const token = 'YOUR_TOKEN_HERE';
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`
|
// Request API.
|
||||||
},
|
axios
|
||||||
done: function(data) {
|
.get('http://localhost:1337/posts', {
|
||||||
console.log('Your data', data);
|
headers: {
|
||||||
},
|
Authorization: `Bearer ${token}`
|
||||||
fail: function(error) {
|
}
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
// Handle success.
|
||||||
|
console.log('Data: ', response.data);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Send forgot password request.
|
## Forgotten password
|
||||||
|
|
||||||
This action sends an email to a user with the link of you reset password page. This link contains an URL param `code` which is required to reset user password.
|
This action sends an email to a user with the link of you reset password page. This link contains an URL param `code` which is required to reset user password.
|
||||||
|
|
||||||
@ -123,23 +133,25 @@ This action sends an email to a user with the link of you reset password page. T
|
|||||||
it is used to redirect the user to the new-password form.
|
it is used to redirect the user to the new-password form.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'POST',
|
|
||||||
url: 'http://localhost:1337/auth/forgot-password',
|
// Request API.
|
||||||
data: {
|
axios
|
||||||
|
.post('http://localhost:1337/auth/forgot-password', {
|
||||||
email: 'user@strapi.io',
|
email: 'user@strapi.io',
|
||||||
url: 'http:/localhost:1337/admin/plugins/users-permissions/auth/reset-password'
|
url: 'http:/localhost:1337/admin/plugins/users-permissions/auth/reset-password'
|
||||||
},
|
})
|
||||||
done: function() {
|
.then(response => {
|
||||||
|
// Handle success.
|
||||||
console.log('Your user received an email');
|
console.log('Your user received an email');
|
||||||
},
|
})
|
||||||
fail: function(error) {
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Reset user password.
|
## Password reset
|
||||||
|
|
||||||
This action will reset the user password.
|
This action will reset the user password.
|
||||||
|
|
||||||
@ -148,24 +160,28 @@ This action will reset the user password.
|
|||||||
- `code` is the url params received from the email link (see forgot password)
|
- `code` is the url params received from the email link (see forgot password)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
$.ajax({
|
import axios from 'axios';
|
||||||
type: 'POST',
|
|
||||||
url: 'http://localhost:1337/auth/reset-password',
|
// Request API.
|
||||||
data: {
|
axios
|
||||||
|
.post('http://localhost:1337/auth/reset-password', {
|
||||||
code: 'privateCode',
|
code: 'privateCode',
|
||||||
password: 'myNewPassword',
|
password: 'myNewPassword',
|
||||||
passwordConfirmation: 'myNewPassword'
|
passwordConfirmation: 'myNewPassword'
|
||||||
},
|
})
|
||||||
done: function() {
|
.then(response => {
|
||||||
console.log('Your user password is reset');
|
// Handle success.
|
||||||
},
|
console.log('Your user\'s password has been changed.');
|
||||||
fail: function(error) {
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Handle error.
|
||||||
console.log('An error occurred:', error);
|
console.log('An error occurred:', error);
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## User Object In Strapi Context
|
## User object in Strapi context
|
||||||
|
|
||||||
The `user` object is available to successfully authenticated requests.
|
The `user` object is available to successfully authenticated requests.
|
||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
@ -190,7 +206,7 @@ The `user` object is available to successfully authenticated requests.
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Add a new provider
|
## Adding a new provider
|
||||||
|
|
||||||
To add a new provider on Strapi, you will need to perform changes onto the following files:
|
To add a new provider on Strapi, you will need to perform changes onto the following files:
|
||||||
|
|
||||||
@ -257,9 +273,9 @@ You may also want to take a look onto the numerous already made configurations [
|
|||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
// Combine username and discriminator because discord username is not unique
|
// Combine username and discriminator because discord username is not unique
|
||||||
var username = `${body.username}#${body.discriminator}`;
|
const username = `${body.username}#${body.discriminator}`;
|
||||||
callback(null, {
|
callback(null, {
|
||||||
username: username,
|
username,
|
||||||
email: body.email
|
email: body.email
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -322,7 +338,7 @@ As for backend, we have a `switch...case` where we need to put our new provider
|
|||||||
Add the corresponding translation into: `packages/strapi-plugin-users-permissions/admin/src/translations/en.json`
|
Add the corresponding translation into: `packages/strapi-plugin-users-permissions/admin/src/translations/en.json`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
"PopUpForm.Providers.discord.providerConfig.redirectURL": "The redirect URL to add in your Discord application configurations",
|
'PopUpForm.Providers.discord.providerConfig.redirectURL': 'The redirect URL to add in your Discord application configurations',
|
||||||
````
|
````
|
||||||
|
|
||||||
These two change will set up the popup message who appear on the UI when we will configure our new provider.
|
These two change will set up the popup message who appear on the UI when we will configure our new provider.
|
||||||
|
@ -10,7 +10,9 @@ Go further with Strapi, official and community tutorials are here to help you:
|
|||||||
### Development
|
### Development
|
||||||
|
|
||||||
- [Building a static blog using Gatsby and Strapi (official)](https://hackernoon.com/building-a-static-blog-using-gatsby-and-strapi-8b5acfc82ad8)
|
- [Building a static blog using Gatsby and Strapi (official)](https://hackernoon.com/building-a-static-blog-using-gatsby-and-strapi-8b5acfc82ad8)
|
||||||
|
- [🍝 Cooking a Deliveroo clone with Nuxt (Vue.js), GraphQL, Strapi and Stripe (official)](https://blog.strapi.io/cooking-a-deliveroo-clone-with-nuxt-vue-js-graphql-strapi-and-stripe-setup-part-1-7)
|
||||||
|
- [🍝 Cooking a Deliveroo clone with Next.js (React), GraphQL, Strapi and Stripe](https://blog.strapi.io/strapi-next-setup)
|
||||||
|
|
||||||
### Deployment
|
### Deployment
|
||||||
|
|
||||||
- [Using mLab with Strapi (official)](https://medium.com/@strapi/using-mlab-with-strapi-e3f968a9c530)
|
- [Using mLab with Strapi (official)](https://medium.com/@strapi/using-mlab-with-strapi-e3f968a9c530)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
meta:
|
meta:
|
||||||
- http-equiv: refresh
|
- http-equiv: refresh
|
||||||
content: 0;url=/documentation/3.x.x/
|
content: 0;url=/documentation/3.x.x/getting-started/installation.html
|
||||||
---
|
---
|
||||||
|
@ -90,9 +90,10 @@
|
|||||||
"app.components.listPlugins.title.plural": "{number} 個のプラグインがインストールされました",
|
"app.components.listPlugins.title.plural": "{number} 個のプラグインがインストールされました",
|
||||||
"app.components.listPlugins.title.singular": "{number} 個のプラグインがインストールされました",
|
"app.components.listPlugins.title.singular": "{number} 個のプラグインがインストールされました",
|
||||||
"app.components.listPluginsPage.deletePlugin.error": "アンインストール中にエラーが発生しました",
|
"app.components.listPluginsPage.deletePlugin.error": "アンインストール中にエラーが発生しました",
|
||||||
"app.utils.SelectOption.defaultMessage": " ",
|
|
||||||
"app.utils.defaultMessage": " ",
|
"app.utils.defaultMessage": " ",
|
||||||
|
"app.utils.delete": "削除",
|
||||||
"app.utils.placeholder.defaultMessage": " ",
|
"app.utils.placeholder.defaultMessage": " ",
|
||||||
|
"app.utils.SelectOption.defaultMessage": " ",
|
||||||
"components.AutoReloadBlocker.description": "以下のファイルを開いて、有効化してください",
|
"components.AutoReloadBlocker.description": "以下のファイルを開いて、有効化してください",
|
||||||
"components.AutoReloadBlocker.header": "プラグインを有効化するにはリロードが必要です",
|
"components.AutoReloadBlocker.header": "プラグインを有効化するにはリロードが必要です",
|
||||||
"components.ErrorBoundary.title": "なにかが間違っています...",
|
"components.ErrorBoundary.title": "なにかが間違っています...",
|
||||||
@ -137,4 +138,4 @@
|
|||||||
"notification.error": "エラーが発生しました",
|
"notification.error": "エラーが発生しました",
|
||||||
"notification.error.layout": "レイアウトを復旧できませんでした",
|
"notification.error.layout": "レイアウトを復旧できませんでした",
|
||||||
"request.error.model.unknown": "modelが存在しません"
|
"request.error.model.unknown": "modelが存在しません"
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ module.exports = {
|
|||||||
|
|
||||||
// Copy Markdown files with some information.
|
// Copy Markdown files with some information.
|
||||||
'README.md': {
|
'README.md': {
|
||||||
template: 'README.md'
|
template: 'CLI.md'
|
||||||
},
|
},
|
||||||
|
|
||||||
// Empty API directory.
|
// Empty API directory.
|
||||||
|
@ -174,7 +174,10 @@ module.exports = function (strapi) {
|
|||||||
_.forEach(postLifecycle, (fn, key) => {
|
_.forEach(postLifecycle, (fn, key) => {
|
||||||
if (_.isFunction(target[model.toLowerCase()][fn])) {
|
if (_.isFunction(target[model.toLowerCase()][fn])) {
|
||||||
collection.schema.post(key, function (doc, next) {
|
collection.schema.post(key, function (doc, next) {
|
||||||
target[model.toLowerCase()][fn](this, doc).then(next).catch(err => strapi.log.error(err));
|
target[model.toLowerCase()][fn](this, doc).then(next).catch(err => {
|
||||||
|
strapi.log.error(err);
|
||||||
|
next(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -16,7 +16,7 @@ const files = glob
|
|||||||
.filter(f => changedFiles.has(f))
|
.filter(f => changedFiles.has(f))
|
||||||
.filter(
|
.filter(
|
||||||
package =>
|
package =>
|
||||||
!package.includes('README.md') &&
|
!package.includes('CLI.md') &&
|
||||||
!package.includes('strapi-middleware-views') &&
|
!package.includes('strapi-middleware-views') &&
|
||||||
!package.includes('strapi-lint') &&
|
!package.includes('strapi-lint') &&
|
||||||
!package.includes('strapi-plugin-settings-manager'),
|
!package.includes('strapi-plugin-settings-manager'),
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "すべてクリア",
|
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "すべてクリア",
|
||||||
"components.FiltersPickWrapper.PluginHeader.description": "エントリをフィルタリングするための条件を設定する",
|
"components.FiltersPickWrapper.PluginHeader.description": "エントリをフィルタリングするための条件を設定する",
|
||||||
"components.FiltersPickWrapper.PluginHeader.title.filter": "フィルタ",
|
"components.FiltersPickWrapper.PluginHeader.title.filter": "フィルタ",
|
||||||
"components.filterspickwrapper.hide": "隠す",
|
"components.FiltersPickWrapper.hide": "隠す",
|
||||||
"components.LimitSelect.itemsPerPage": "ページあたりのアイテム数",
|
"components.LimitSelect.itemsPerPage": "ページあたりのアイテム数",
|
||||||
"components.Search.placeholder": "エントリを検索する...",
|
"components.Search.placeholder": "エントリを検索する...",
|
||||||
"components.TableDelete.delete": "すべて削除",
|
"components.TableDelete.delete": "すべて削除",
|
||||||
@ -111,4 +111,4 @@
|
|||||||
"popUpWarning.warning.updateAllSettings": "これにより、すべての設定が変更されます",
|
"popUpWarning.warning.updateAllSettings": "これにより、すべての設定が変更されます",
|
||||||
"success.record.delete": "削除",
|
"success.record.delete": "削除",
|
||||||
"success.record.save": "保存"
|
"success.record.save": "保存"
|
||||||
}
|
}
|
||||||
|
@ -106,11 +106,12 @@ module.exports = {
|
|||||||
|
|
||||||
const request = await this.create(values)
|
const request = await this.create(values)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
const message = err.message.split('index:');
|
if (err.message) {
|
||||||
const field = _.words(_.last(message).split('_')[0]);
|
const message = err.message.split('index:');
|
||||||
const error = { message: `This ${field} is already taken`, field };
|
const field = _.words(_.last(message).split('_')[0]);
|
||||||
|
err = { message: `This ${field} is already taken`, field };
|
||||||
throw error;
|
}
|
||||||
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Transform to JSON object.
|
// Transform to JSON object.
|
||||||
|