Merge branch 'master' into patch-1

This commit is contained in:
Alexandre BODIN 2019-12-09 10:03:47 +01:00 committed by GitHub
commit 232363beec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 295 additions and 37 deletions

View File

@ -200,6 +200,7 @@ module.exports = {
'/3.0.0-beta.x/guides/external-data',
'/3.0.0-beta.x/guides/custom-data-response',
'/3.0.0-beta.x/guides/custom-admin',
'/3.0.0-beta.x/guides/draft',
'/3.0.0-beta.x/guides/slug',
'/3.0.0-beta.x/guides/webhooks',
],

View File

@ -2,8 +2,6 @@
Strapi comes with a full featured Command Line Interface (CLI) which lets you scaffold and manage your project in seconds.
---
## strapi new
Create a new project.
@ -245,8 +243,6 @@ strapi generate:plugin <name>
Please refer to the [local plugins](../plugin-development/quick-start.md) section to know more.
---
## strapi install
Install a plugin in the project.
@ -264,8 +260,6 @@ strapi install <name>
Some plugins have admin panel integrations, your admin panel might have to be rebuilt. This can take some time.
:::
---
## strapi uninstall
Uninstall a plugin from the project.
@ -290,7 +284,13 @@ options [--delete-files]
Some plugins have admin panel integrations, your admin panel might have to be rebuilt. This can take some time.
:::
---
## strapi console
Start the server and let you eval commands into your application in real time.
```bash
strapi console
```
## strapi version
@ -300,8 +300,6 @@ Print the current globally installed Strapi version.
strapi version
```
---
## strapi help
List CLI commands.

View File

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

View File

@ -0,0 +1,123 @@
# Draft system
This guide will explain how to create draft system. That will you manage draft, published, archive status.
## Introduction
What we want here is to fetch only data that have a `published` status.
But we don't want to use [parameters](../content-api/parameters.md) (eg. /articles?status=published) because you can easily fake the params.
To be able to do that, you have first to understand some concepts.
When you create a content type, it generates an API with the following list of [endpoints](../content-api/endpoint.md).
Each of these endpoint triggers a controller action. Here is the list of [controller actions](../concepts/controller.md) that exist by default when a content type is created.
If you check the controller file of your generated API `./api/{content-type}/controller/{Content-Type}.js`, you will see an empty file. It is because all the default logic is managed by Strapi. But you can override these actions with your own code.
And that is what we will do to filter to `published` status by default.
## Example
In our example we will use an Article content type. By default when you fetch articles, you will got all articles.
Let's consider you don't want to expose articles that are in `draft` or `archive` status.
To enforce this rule we will customize the action that fetchs all articles to just fetch `published` articles.
To follow the example your will have to create a content type `articles` and add the following field definition:
- `string` attribute named `title`
- `text` attribute named `content`
- `enumeration` attribute named `status` with `draft`, `published`, `archive`
Then add some data with different `status`.
## Override controller action
To customize the function that fetch all our articles we will have to override the `find` function.
First, to see the difference, let's request `GET /articles`. You will see all the data you created.
Now let's start the customization.
**Path —** `./api/article/controller/Article.js`
```js
module.exports = {
async find() {
return 'strapi';
},
};
```
After saving the new function, let's restart the `GET /articles` request. We will see `strapi` as response.
## Get the data back
We now know the function we have to update, but we just want to customize the returned article values.
In the [controller documentation](../concepts/controllers.html#extending-a-model-controller) you will find the default implementation of every actions. It will help you overwrite the fetch logic.
**Path —** `./api/article/controller/Article.js`
```js
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
async find(ctx) {
let entities;
if (ctx.query._q) {
entities = await strapi.services.article.search(ctx.query);
} else {
entities = await strapi.services.article.find(ctx.query);
}
return entities.map(entity =>
sanitizeEntity(entity, { model: strapi.models.article })
);
},
};
```
And now the data is back on `GET /articles`
## Apply our changes
Here we want force to fetch articles that have status equal to `published`.
The way to do that is to set `ctx.query.status` to `published`.
It will force the filter of the query.
**Path —** `./api/restaurant/controller/Restaurant.js`
```js
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
async find(ctx) {
let entities;
ctx.query = {
...ctx.query,
status: 'published
};
if (ctx.query._q) {
entities = await strapi.services.article.search(ctx.query);
} else {
entities = await strapi.services.article.find(ctx.query);
}
return entities.map(entity =>
sanitizeEntity(entity, { model: strapi.models.article })
);
},
};
```
And tada! Draft and archived articles disapeared.
::: tip
This guide can be applied to any other controller action.
:::

View File

@ -2,6 +2,7 @@
"Analytics": "통계",
"Content Manager": "콘텐츠 관리",
"Content Type Builder": "콘텐츠 타입 빌더",
"Documentation": "문서",
"Email": "이메일",
"Files Upload": "파일 업로드",
"HomePage.notification.newsLetter.success": "뉴스레터 구독을 완료했습니다.",
@ -80,8 +81,8 @@
"app.components.ListPluginsPage.helmet.title": "플러그인 목록",
"app.components.ListPluginsPage.title": "플러그인",
"app.components.Logout.admin": "관리자 계정관리",
"app.components.Logout.profile": "옆모습",
"app.components.Logout.logout": "로그 아웃",
"app.components.Logout.profile": "프로필",
"app.components.Logout.logout": "로그아웃",
"app.components.NotFoundPage.back": "홈으로 돌아가기",
"app.components.NotFoundPage.description": "찾을 수 없는 페이지입니다.",
"app.components.Official": "공식",
@ -124,6 +125,7 @@
"components.Input.error.validation.minSupMax": "이 보다 더 클 수 없습니다.",
"components.Input.error.validation.regex": "입력한 내용이 형식에 맞지 않습니다.",
"components.Input.error.validation.required": "내용을 입력해 주세요.",
"components.InputSelect.option.placeholder": "선택해 주세요.",
"components.ListRow.empty": "데이터가 없습니다.",
"components.OverlayBlocker.description": "이 기능은 서버를 재시작해야 합니다. 서버가 시작될 때까지 잠시만 기다려주세요.",
"components.OverlayBlocker.description.serverError": "서버가 재시작되지 않았습니다. 터미널에서 로그를 확인하십시오.",
@ -154,14 +156,26 @@
"notification.error.layout": "레이아웃을 가져올 수 없습니다.",
"request.error.model.unknown": "모델이 없습니다.",
"app.utils.delete": "삭제",
"HomePage.helmet.title": "홈페이지",
"HomePage.welcome.congrats": "축하합니다!",
"HomePage.welcome.congrats.content": "첫번째 관리자로 로그인하셨습니다. Strapi의 강력한 기능을 확인하시려면,",
"HomePage.welcome.congrats.content.bold": "첫번째 콘텐츠 타입 생성을 해보시길 추천드립니다.",
"HomePage.community": "커뮤니티 참여",
"HomePage.roadmap": "로드맵 보기",
"HomePage.greetings": "안녕하세요 {name}님!",
"Auth.advanced.allow_register": "",
"Auth.privacy-policy-agreement.terms": "약관",
"Auth.privacy-policy-agreement.policy": "개인정보 보호정책",
"Auth.form.button.forgot-password": "메일 보내기",
"Auth.form.button.forgot-password.success": "다시 보내기",
"Auth.form.button.login": "로그인",
"Auth.form.button.register": "등록",
"Auth.form.button.register-success": "다시 보내기",
"Auth.form.button.reset-password": "패스워드 변경",
"Auth.form.error.blocked": "관리자에 의해 접근이 제한된 계정입니다.",
"Auth.form.error.code.provide": "유효하지 않은 코드입니다.",
"Auth.form.error.confirmed": "이메일 인증이 필요합니다.",
"Auth.form.error.email.invalid": "유효하지 않은 이메일입니다.",
"Auth.form.error.email.provide": "이메일을 입력해 주세요.",
"Auth.form.error.email.taken": "이미 사용 중인 이메일입니다.",
@ -172,6 +186,7 @@
"Auth.form.error.password.local": "비밀번호를 설정하지 않았습니다. 다른 방법으로 로그인 하세요.",
"Auth.form.error.password.matching": "패스워드가 일치하지 않습니다.",
"Auth.form.error.password.provide": "패스워드를 입력해 주세요.",
"Auth.form.error.ratelimit": "요청이 너무 많습니다. 잠시 후 다시 시도해주세요.",
"Auth.form.error.user.not-exist": "이메일이 없습니다.",
"Auth.form.error.username.taken": "이미 사용 중인 아이디입니다.",
"Auth.form.forgot-password.email.label": "메일 주소를 입력하세요.",
@ -190,11 +205,15 @@
"Auth.form.register.confirmPassword.label": "패스워드 확인",
"Auth.form.register.email.label": "이메일",
"Auth.form.register.email.placeholder": "johndoe@gmail.com",
"Auth.form.register.news.label": "새 기능과 향후 개선 사항에 대한 최신 정보를 계속 제공해주세요 (선택시 {terms}과 {policy}에 동의하는 걸로 간주됩니다).",
"Auth.form.register.password.label": "패스워드",
"Auth.form.register.username.label": "아이디",
"Auth.form.register.username.placeholder": "JohnDoe",
"Auth.header.register.description": "애플리케이션 설정 및 보안을 위해 첫 번째 사용자(root 관리자)를 생성하세요.",
"Auth.link.forgot-password": "패스워드 재설정",
"Auth.link.ready": "로그인 하시겠습니까?",
"components.Input.error.password.noMatch": "패스워드가 일치하지 않습니다."
}
"app.containers.App.notification.error.init": "API 요청 중에 에러가 발생했습니다.",
"components.Input.error.password.noMatch": "패스워드가 일치하지 않습니다.",
"form.button.done": "확인",
"notification.form.error.fields": "잘못 입력된 필드가 존재합니다."
}

View File

@ -546,8 +546,8 @@ const buildSearchQuery = (qb, model, params) => {
case 'pg': {
const searchQuery = searchText.map(attribute =>
_.toLower(attribute) === attribute
? `to_tsvector(${attribute})`
: `to_tsvector("${attribute}")`
? `to_tsvector(coalesce(${attribute}, ''))`
: `to_tsvector(coalesce("${attribute}", ''))`
);
qb.orWhereRaw(`${searchQuery.join(' || ')} @@ plainto_tsquery(?)`, query);

View File

@ -1,8 +1,15 @@
{
"models": "콘텐츠 타입",
"models.numbered": "콘텐츠 타입 ({number}개)",
"groups": "그룹",
"groups.numbered": "그룹 ({number}개)",
"EditRelations.title": "관계 데이터",
"components.AddFilterCTA.add": "필터",
"components.AddFilterCTA.hide": "필터",
"components.DraggableAttr.edit": "클릭하여 수정",
"components.EmptyAttributesBlock.button": "설정 페이지 이동",
"components.EmptyAttributesBlock.description": "설정을 변경할 수 있습니다.",
"components.FieldItem.linkToGroupLayout": "그룹 레이아웃 설정",
"components.FilterOptions.FILTER_TYPES.=": "같음",
"components.FilterOptions.FILTER_TYPES._contains": "포함",
"components.FilterOptions.FILTER_TYPES._containss": "포함(대소문자 구분)",
@ -11,26 +18,39 @@
"components.FilterOptions.FILTER_TYPES._lt": "작음",
"components.FilterOptions.FILTER_TYPES._lte": "작거나 같음",
"components.FilterOptions.FILTER_TYPES._ne": "같지 않음",
"components.FilterOptions.FILTER_TYPES._in": "배열중에 일치하는 값이 있음",
"components.FilterOptions.FILTER_TYPES._nin": "배열중에 일치하는 값이 없음",
"components.FilterOptions.button.apply": "적용",
"components.FiltersPickWrapper.PluginHeader.actions.apply": "적용",
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "모두 재설정",
"components.FiltersPickWrapper.PluginHeader.description": "필터링 조건을 설정하세요.",
"components.FiltersPickWrapper.PluginHeader.title.filter": "필터",
"components.FiltersPickWrapper.hide": "숨김",
"components.Group.notification.info.minimum-requirement": "최소 갯수가 맞지 않아 필드가 추가되었습니다.",
"components.Group.notification.info.maximum-requirement": "더 이상 필드를 추가할 수 없습니다.",
"components.Group.empty.repeatable": "항목이 없습니다. 아래 버튼을 눌러 추가해주세요.",
"components.Group.reset": "초기화",
"components.LimitSelect.itemsPerPage": "항목 수 / 페이지",
"components.Search.placeholder": "검색 중입니다...",
"components.TableDelete.delete": "모두 삭제",
"components.TableDelete.deleteSelected": "선택된 것을 지워 라",
"components.TableDelete.deleteSelected": "선택항목 삭제",
"components.TableDelete.entries.plural": "{number}개 항목 선택 됨",
"components.TableDelete.entries.singular": "{number}개 항목 선택 됨",
"components.TableEmpty.withFilters": "필터 조건에 맞는 {contentType} 목록이 없습니다.",
"components.TableEmpty.withSearch": "\"{search}\" 검색. {contentType} 목록이 없습니다.",
"components.TableEmpty.withoutFilter": "{contentType} 목록이 없습니다.",
"containers.Edit.addAnItem": "추가할 항목...",
"containers.Edit.pluginHeader.title.new": "항목 생성",
"containers.Edit.clickToJump": "해당 항목으로 이동하려면 클릭",
"containers.Edit.delete": "삭제",
"containers.Edit.editing": "수정 중...",
"containers.Edit.reset": "재설정",
"containers.Edit.reset": "초기화",
"containers.Edit.returnList": "목록",
"containers.Edit.seeDetails": "세부 사항",
"containers.Edit.submit": "저장",
"containers.Edit.Link.Layout": "레이아웃 설정",
"containers.Edit.Link.Fields": "필드 수정",
"containers.EditView.notification.errors": "잘못 입력된 필드가 존재합니다.",
"containers.Home.introduction": "항목을 수정하려면 왼편 링크를 클릭하세요. 이 플러그인은 설정을 편집할 수 있는 방법을 개발 중입니다.",
"containers.Home.pluginHeaderDescription": "쉽고 강력한 UI를 통해 항목들을 관리 하세요.",
"containers.Home.pluginHeaderTitle": "콘텐츠 관리",
@ -38,17 +58,30 @@
"containers.List.errorFetchRecords": "에러",
"containers.List.pluginHeaderDescription": "{label}개 항목",
"containers.List.pluginHeaderDescription.singular": "{label}개 항목",
"containers.ListPage.displayedFields": "표시 필드",
"containers.SettingPage.addField": "새 필드 추가",
"containers.SettingPage.addRelationalField": "새 관계 필드 추가",
"containers.SettingPage.attributes": "속성",
"containers.SettingPage.attributes.description": "속성의 순서를 지정합니다",
"containers.SettingPage.editSettings.description": "레이아웃을 만들기 위해 필드를 드래그 & 드랍하세요.",
"containers.SettingPage.editSettings.title": "화면 수정 (설정)",
"containers.SettingPage.editSettings.entry.title": "항목 제목",
"containers.SettingPage.editSettings.entry.title.description": "제목으로 보여줄 필드를 선택하세요.",
"containers.SettingPage.listSettings.description": "이 콘텐츠 유형의 옵션을 구성합니다.",
"containers.SettingPage.listSettings.title": "목록 (설정)",
"containers.SettingPage.pluginHeaderDescription": "이 콘텐츠 유형에 특정한 설정을 구성합니다.",
"containers.SettingPage.relations": "관계 필드",
"containers.SettingPage.settings": "설정",
"containers.SettingPage.layout": "레이아웃",
"containers.EditView.Group.add.new": "새 항목 추가",
"containers.SettingViewModel.pluginHeader.title": "콘텐츠 매니저 - {name}",
"containers.SettingsPage.Block.contentType.description": "특정 설정을 구성합니다.",
"containers.SettingsPage.Block.contentType.title": "콘텐츠 유형",
"containers.SettingsPage.Block.generalSettings.description": "콘텐츠 유형에 대한 기본 옵션을 구성합니다.",
"containers.SettingsPage.Block.generalSettings.title": "일반",
"containers.SettingsPage.pluginHeaderDescription": "모든 콘텐츠 유형에 대한 기본 설정을 구성합니다.",
"containers.SettingsView.list.title": "표시 설정",
"containers.SettingsView.list.subtitle": "레이아웃, 콘텐츠 타입과 그룹의 표시 방법을 설정합니다.",
"emptyAttributes.button": "콘텐츠 유형 빌더",
"emptyAttributes.description": "첫번째 필드를 추가하세요.",
"emptyAttributes.title": "아직 필드가 없습니다.",
@ -74,14 +107,22 @@
"error.validation.required": "내용을 입력해 주세요.",
"form.Input.bulkActions": "대규모 액션 활성화",
"form.Input.defaultSort": "기본 정렬 속성",
"form.Input.description": "설명",
"form.Input.description.placeholder": "Display name in the profile",
"form.Input.editable": "필드 수정가능 여부",
"form.Input.filters": "필더 활성화",
"form.Input.label": "라벨",
"form.Input.label.inputDescription": "이 값은 테이블 머리에 표시된 라벨을 덮어씌웁니다.",
"form.Input.pageEntries": "페이지 당 요소",
"form.Input.pageEntries.inputDescription": "참고 : 콘텐츠 유형 설정에서 이 값을 덮어씌울 수 있습니다.",
"form.Input.placeholder": "Placeholder",
"form.Input.placeholder.placeholder": "My awesome value",
"form.Input.search": "검색 활성화",
"form.Input.search.field": "이 필드에 검색 활성화",
"form.Input.sort.field": "이 필드에 정렬 활성화",
"form.Input.wysiwyg": "WYSIWYG로 보기",
"global.displayedFields": "표시 필드",
"notification.error.displayedFields": "표시될 필드가 최소 하나 이상 필요합니다.",
"notification.error.relationship.fetch": "데이터 관계를 가져오는 도중 에러가 발생했습니다.",
"notification.info.SettingPage.disableSort": "정렬이 활성화된 한 개의 속성이 필요합니다.",
"pageNotFound": "페이지를 찾을 수 없습니다.",
@ -95,5 +136,7 @@
"popUpWarning.warning.cancelAllSettings": "수정 사항을 취소하시겠습니까?",
"popUpWarning.warning.updateAllSettings": "모든 설정에 적용됩니다.",
"success.record.delete": "삭제",
"success.record.save": "저장"
"success.record.save": "저장",
"notification.info.minimumFields": "표시될 필드가 최소 하나 이상 필요합니다.",
"notification.upload.error": "파일 업로드 중에 에러가 발생했습니다."
}

View File

@ -1,4 +1,6 @@
{
"model": "콘텐츠 타입",
"group": "그룹",
"attribute.WYSIWYG": "WYSIWYG 텍스트(Text)",
"attribute.boolean": "불리언(Boolean)",
"attribute.date": "날짜(Date)",
@ -6,29 +8,42 @@
"attribute.email": "이메일(Email)",
"attribute.enumeration": "열거(Enumeration)",
"attribute.float": "숫자(Float)",
"attribute.group": "그룹(Group)",
"attribute.integer": "숫자(integer)",
"attribute.biginteger": "Big Integer",
"attribute.json": "JSON",
"attribute.media": "미디어(Media)",
"attribute.password": "패스워드(Password)",
"attribute.relation": "관계(Relation)",
"attribute.richtext": "서식있는 텍스트(Rich text)",
"attribute.string": "문자(String)",
"attribute.text": "텍스트(Text)",
"attribute.uuid": "Uuid",
"button.attributes.add": "필드 추가",
"button.attributes.add.another": "새 필드 추가",
"button.contentType.add": "콘텐츠 타입 추가",
"button.delete.title": "삭제",
"button.delete.label": "정말 삭제하시겠습니까?",
"button.group.add": "그룹 추가",
"button.models.create": "콘텐츠 타입 만들기",
"button.groups.create": "그룹 만들기",
"contentType.temporaryDisplay": "(저장되지 않음)",
"error.attribute.forbidden": "사용할 수 없는 이름입니다.(예약어)",
"error.attribute.key.taken": "이미 사용중인 키입니다.",
"error.attribute.sameKeyAndName": "같을 수 없습니다.",
"error.attribute.taken": "이미 사용중인 이름입니다.",
"error.contentTypeName.taken": "이미 사용중인 이름입니다.",
"error.contentTypeName.reserved-name": "이 이름은 다른 기능에 문제를 야기할수 있으므로 사용할 수 없습니다.",
"error.validation.max": "입력한 내용이 너무 큽니다.",
"error.validation.maxLength": "입력한 내용이 너무 깁니다.",
"error.validation.min": "입력한 내용이 너무 작습니다.",
"error.validation.minLength": "입력한 내용이 너무 짧습니다.",
"error.validation.minSupMax": "이 보다 더 클 수 없습니다.",
"error.validation.regex": "입력한 내용이 형식에 맞지 않습니다.",
"error.validation.regex.name": "이름은 알파벳 문자로 시작해야 합니다. 밑줄과 숫자는 두번째 문자부터 허용됩니다.",
"error.validation.regex.values": "값은 숫자나 특수문자로 시작할 수 없습니다.",
"error.validation.required": "내용을 입력해 주세요.",
"form.attribute.info.no-space-allowed": "속성의 이름에 공백은 허용되지 않습니다.",
"form.attribute.item.appearance.description": "혹은 기본 textarea로 내용을 편집할 수 있습니다.",
"form.attribute.item.appearance.label": "WYSIWYG으로 보기",
"form.attribute.item.appearance.name": "모양",
@ -41,7 +56,11 @@
"form.attribute.item.enumeration.graphql.description": "기본 생성된 이름을 GraphQL에서 사용합니다.",
"form.attribute.item.enumeration.name": "이름",
"form.attribute.item.enumeration.placeholder": "Ex:\nmorning\nnoon\nevening",
"form.attribute.item.enumeration.rules": "Values (one line per value)",
"form.attribute.item.enumeration.rules": "값 (한 줄에 하나씩 입력)",
"form.attribute.item.group.label.name": "이 콘텐츠 타입에서의 그룹 이름",
"form.attribute.item.group.label.select": "그룹 선택",
"form.attribute.item.group.placeholder.name": "선택한 그룹의 이름",
"form.attribute.item.group.placeholder.select": "목록에서 그룹을 선택하세요.",
"form.attribute.item.json.name": "이름",
"form.attribute.item.maximum": "최대 값",
"form.attribute.item.maximumLength": "최대 길이",
@ -51,9 +70,12 @@
"form.attribute.item.minimumLength": "최소 길이",
"form.attribute.item.number.name": "이름",
"form.attribute.item.number.type": "숫자 형식",
"form.attribute.item.number.type.decimal": "decimal (ex: 2.22)",
"form.attribute.item.number.type.float": "float (ex: 3.33333333)",
"form.attribute.item.number.type.integer": "integer (ex: 10)",
"form.attribute.item.number.type.decimal": "소수 (ex: 2.22)",
"form.attribute.item.number.type.float": "실수 (ex: 3.33333333)",
"form.attribute.item.number.type.integer": "정수 (ex: 10)",
"form.attribute.item.number.type.biginteger": "big integer (ex: 123456789)",
"form.attribute.item.repeatable": "Repeatable field",
"form.attribute.item.repeatable.description": "내용이 동일한 기존 항목이 있는 경우 항목을 만들 수 없습니다.",
"form.attribute.item.requiredField": "필수 항목",
"form.attribute.item.requiredField.description": "필수 항목일 경우 체크하세요.",
"form.attribute.item.settings.name": "설정",
@ -63,32 +85,41 @@
"form.attribute.item.uniqueField.description": "유일한 값만 허용 할 경우 체크하세요.",
"form.attribute.settings.default": "기본값",
"form.attribute.settings.default.checkboxLabel": "true로 설정",
"form.button.add.field": "계속해서 필드 추가",
"form.button.cancel": "취소",
"form.button.continue": "다음",
"form.button.save": "저장",
"form.contentType.item.collectionName": "컬렉션 이름",
"form.contentType.item.collectionName.inputDescription": "콘텐츠 타입 이름과 테이블 이름이 다를 경우 유용합니다.",
"form.modelForm.item.collectionName.inputDescription": "{featureType} 이름과 테이블 이름이 다를 경우 유용합니다.",
"form.contentType.item.connections": "연결",
"form.contentType.item.description": "설명",
"form.contentType.item.description.placeholder": "간략한 설명을 작성하세요.",
"form.contentType.item.name": "이름",
"form.contentType.item.name.description": "콘텐츠 타입 이름은 단수형이어야 합니다. {link}",
"form.modelForm.item.name.description.featureType": "{featureType} 이름은 단수형이어야 합니다. {link}",
"form.contentType.item.name.link.description": "문서를 참고하세요.",
"from": "from",
"home.contentTypeBuilder.description": "콘텐츠 타입을 만들거나 업데이트 하세요.",
"home.contentTypeBuilder.name": "콘텐츠 타입 빌더",
"home.emptyAttributes.description": "새 콘텐츠 타입에 첫번째 필드를 추가하세요.",
"home.emptyAttributes.description.model": "새 콘텐츠 타입에 첫번째 필드를 추가하세요.",
"home.emptyAttributes.description.group": "새 그룹에 첫번째 필드를 추가하세요.",
"home.contentTypeBuilder.headerNav.link.models": "콘텐츠 타입",
"home.contentTypeBuilder.headerNav.link.groups": "그룹",
"home.emptyAttributes.title": "아직 필드가 없습니다.",
"home.empty.models.description": "API로 검색 할 수 있게 첫번째 콘텐츠 타입을 만드세요.",
"home.empty.groups.description": "첫번째 그룹을 만드세요.",
"home.empty.models.title": "콘텐츠 타입이 없습니다.",
"home.empty.groups.title": "그룹이 없습니다.",
"menu.section.contentTypeBuilder.name.plural": "콘텐츠 타입",
"menu.section.contentTypeBuilder.name.singular": "콘텐츠 타입",
"home.emptyContentType.description": "API로 검색 할 수 있게 첫번째 콘텐츠 타입을 만드세요.",
"home.emptyContentType.title": "콘텐츠 타입이 없습니다.",
"menu.section.models.name.plural": "콘텐츠 타입",
"menu.section.models.name.singular": "콘텐츠 타입",
"menu.section.groups.name.plural": "Groups",
"menu.section.groups.name.singular": "Group",
"menu.section.groups.name.plural": "그룹",
"menu.section.groups.name.singular": "그룹",
"menu.section.documentation.guide": "콘텐츠 타입",
"menu.section.documentation.guideLink": "가이드",
"menu.section.documentation.name": "문서",
@ -101,13 +132,16 @@
"modelPage.contentType.list.title.including": "포함",
"modelPage.contentType.list.title.plural": "필드",
"modelPage.contentType.list.title.singular": "필드",
"modelPage.contentType.list.group.link": "그룹 수정",
"noTableWarning.description": "데이터베이스에 `{modelName}` 테이블을 생성하세요.",
"noTableWarning.infos": "더보기",
"notification.error.message": "에러가 발생했습니다.",
"notification.info.contentType.creating.notSaved": "새로운 것을 만들기 전에 콘텐츠 타입을 저장하세요.",
"notification.info.work.notSaved": "새로운 것을 만들기 전에 콘텐츠 타입을 저장하세요.",
"notification.info.disable": "현재 수정 할 수 없습니다...😮",
"notification.info.optimized": "이 플러그인은 로컬스토리지에 최적화되어 있습니다.",
"notification.success.contentTypeDeleted": "콘텐츠 타입이 삭제 됐습니다.",
"notification.success.groupDeleted": "그룹이 삭제 됐습니다.",
"notification.success.message.contentType.create": "콘텐츠 타입이 생성 됐습니다.",
"notification.success.message.contentType.edit": "콘텐츠 타입이 업데이트 됐습니다.",
"plugin.description.long": "API를 위한 데이터 구조를 모델링 합니다. 새로운 필드와 릴레이션을 간단히 만드세요. 자동으로 설정 파일이 만들어 지고 프로젝트에 추가됩니다.",
@ -120,6 +154,8 @@
"popUpForm.attributes.email.name": "이메일(Email)",
"popUpForm.attributes.enumeration.description": "선택 목록",
"popUpForm.attributes.enumeration.name": "열거형(Enumeration)",
"popUpForm.attributes.group.description": "그룹을 나타내는 필드",
"popUpForm.attributes.group.name": "Group",
"popUpForm.attributes.json.description": "JSON 형식의 데이터",
"popUpForm.attributes.json.name": "JSON",
"popUpForm.attributes.media.description": "이미지, 비디오, PDF 등등의 파일",
@ -130,13 +166,28 @@
"popUpForm.attributes.password.name": "패스워드(Password)",
"popUpForm.attributes.relation.description": "다른 콘텐츠 타입 참조",
"popUpForm.attributes.relation.name": "관계(Relation)",
"popUpForm.attributes.richtext.description": "서식이 적용된 텍스트",
"popUpForm.attributes.richtext.name": "서식있는 텍스트(Rich text)",
"popUpForm.attributes.string.description": "제목, 이름, 문장, 이름 목록",
"popUpForm.attributes.string.name": "문자(String)",
"popUpForm.attributes.text.description": "설명, 문장, 아티클 ",
"popUpForm.attributes.text.name": "텍스트(Text)",
"popUpForm.attributes.uuid.description": "고유 식별자",
"popUpForm.attributes.uuid.name": "Uuid",
"popUpForm.choose.attributes.header.title": "새 필드 추가",
"popUpForm.choose.attributes.header.subtitle.model": "콘텐츠 타입 필드 생성",
"popUpForm.choose.attributes.header.subtitle.group": "그룹 필드 생성",
"popUpForm.create": "새로운 ",
"popUpForm.create.contentType.header.title": "새 콘텐츠 타입 추가",
"popUpForm.create.contentType.header.subtitle": "콘텐츠 타입 이름 정하기",
"popUpForm.create.model.header.title": "콘텐츠 타입 만들기",
"popUpForm.edit.model.header.title": "콘텐츠 타입 수정하기",
"popUpForm.create.group.header.title": "그룹 만들기",
"popUpForm.edit.group.header.title": "그룹 수정하기",
"popUpForm.create.model.header.subTitle": "콘텐츠 타입 설정",
"popUpForm.edit.model.header.subTitle": "{name} 설정",
"popUpForm.create.group.header.subTitle": "그룹 설정",
"popUpForm.edit.group.header.subTitle": "{name} 설정",
"popUpForm.edit": "수정",
"popUpForm.edit.contentType.header.title": "콘텐츠 타입 수정",
"popUpForm.field": "필드",
@ -146,12 +197,14 @@
"popUpRelation.title": "관계",
"popUpWarning.bodyMessage.attribute.delete": "이 필드를 삭제 하시겠습니까?",
"popUpWarning.bodyMessage.contentType.delete": "이 콘텐츠 타입을 삭제 하시겠습니까?",
"popUpWarning.bodyMessage.groups.delete": "정말 이 그룹을 삭제 하시겠습니까? 콘텐츠 타입에 포함된 그룹도 같이 삭제됩니다.",
"popUpWarning.button.cancel": "취소",
"popUpWarning.button.confirm": "확인",
"popUpWarning.title": "확인",
"relation.attributeName.placeholder": "Ex: author, category, tag",
"relation.manyToMany": "N : N",
"relation.manyToOne": "N : 1",
"relation.manyWay": "has many",
"relation.oneToMany": "1 : N",
"relation.oneToOne": "1 : 1",
"relation.oneWay": "has one",
@ -159,5 +212,12 @@
"table.contentType.head.fields": "필드",
"table.contentType.head.name": "이름",
"table.contentType.title.plural": "{number} 개의 콘텐츠 타입이 있습니다.",
"table.contentType.title.singular": "{number} 개의 콘텐츠 타입이 있습니다."
}
"table.contentType.title.singular": "{number} 개의 콘텐츠 타입이 있습니다.",
"table.groups.title.plural": "{number} 개의 그룹이 있습니다.",
"table.groups.title.singular": "{number} 개의 그룹이 있습니다.",
"table.attributes.title.plural": "{number} 개의 속성이 있습니다.",
"table.attributes.title.singular": "{number} 개의 속성이 있습니다.",
"table.relations.title.plural": "{number} 개의 관계가 있습니다.",
"table.relations.title.singular": "{number} 개의 관계가 있습니다.",
"prompt.content.unsaved": "정말 이 창을 떠나시겠습니까? 모든 수정 사항은 저장되지 않습니다."
}

View File

@ -83,6 +83,11 @@ module.exports = strapi => {
playground: false,
cors: false,
bodyParserConfig: true,
introspection: _.get(
strapi.plugins.graphql,
'config.introspection',
true
),
};
// Disable GraphQL Playground in production environment.
@ -92,10 +97,8 @@ module.exports = strapi => {
) {
serverParams.playground = {
endpoint: strapi.plugins.graphql.config.endpoint,
shareEnabled: strapi.plugins.graphql.config.shareEnabled
shareEnabled: strapi.plugins.graphql.config.shareEnabled,
};
serverParams.introspection = true;
}
const server = new ApolloServer(serverParams);

View File

@ -21,10 +21,11 @@
"PluginInputFile.link": "선택",
"PluginInputFile.loading": "파일을 업로드합니다.",
"PluginInputFile.text": "업로드 할 파일을 끌어 넣거나 {link} 하세요",
"Upload.status.empty": "파일이 비어있습니다.",
"Upload.status.sizeLimit": "{file}이 (가) 구성된 제한 크기보다 큽니다.",
"Upload.status.disabled" : "파일 업로드가 사용 중지되었습니다.",
"notification.config.success": "설정을 업데이트했습니다.",
"notification.delete.success": "파일을 삭제했습니다.",
"notification.dropFile.success": "파일을 업로드했습니다.",
"notification.dropFiles.success": "{number}개의 파일을 업로드 했습니다.",
"Upload.status.sizeLimit": "{file}이 (가) 구성된 제한 크기보다 큽니다.",
"Upload.status.disabled" : "파일 업로드가 사용 중지되었습니다."
"notification.dropFiles.success": "{number}개의 파일을 업로드 했습니다."
}

View File

@ -2,6 +2,7 @@
"BoundRoute.title": "라우트(bound route)",
"Controller.input.label": "{label} ",
"Controller.selectAll": "전체 선택",
"Controller.unselectAll": "전체 선택 해제",
"EditForm.inputSelect.description.role": "인증된 사용자에 선택한 역할(role)을 부여합니다.",
"EditForm.inputSelect.durations.description": "사용자가 사용할 수 없는 시간을 설정합니다.",
"EditForm.inputSelect.durations.label": "기간(duration)",
@ -9,8 +10,14 @@
"EditForm.inputSelect.subscriptions.description": "동일 IP에서 시간당 사용할 수 있는 횟수를 제한합니다.",
"EditForm.inputSelect.subscriptions.label": "사용량 관리",
"EditForm.inputToggle.description.email": "사용자가 동일한 이메일 주소를 사용해 여러 계정을 만들지 못하게 합니다.",
"EditForm.inputToggle.description.email-confirmation": "(ON)이 활성화되면, 새로 가입하는 사용자는 인증 메일을 받게됩니다.",
"EditForm.inputToggle.description.email-confirmation-redirection": "이메일 인증완료 후 리다이렉트 될 주소",
"EditForm.inputToggle.description.email-reset-password": "애플리케이션의 비밀번호 재설정 URL 페이지",
"EditForm.inputToggle.description.sign-up": "비활성(OFF)일 경우, 등록 프로세스를 금지합니다. 사용하는 프로바이더(provider)에 관계 없이 누구도 가입할 수 없습니다.",
"EditForm.inputToggle.label.email": "이메일 주소 당 하나의 계정",
"EditForm.inputToggle.label.email-confirmation": "이메일 인증 활성화",
"EditForm.inputToggle.label.email-confirmation-redirection": "리다이렉션 url",
"EditForm.inputToggle.label.email-reset-password": "패스워드 재설정 페이지",
"EditForm.inputToggle.label.sign-up": "사용자 등록",
"EditPage.cancel": "취소",
"EditPage.form.roles": "역할(role) 세부설정",
@ -26,9 +33,9 @@
"EditPage.notification.policies.error": "정책(policies)를 가져오는데 에러가 발생했습니다.",
"EditPage.notification.role.error": "역할(role)을 가져오는데 에러가 발생했습니다.",
"EditPage.submit": "저장",
"Email.template.email_confirmation": "이메일 주소 인증",
"Email.template.reset_password": "패스워드 재설정",
"Email.template.success_register": "등록했습니다.",
"Email.template.validation_email": "이메일 주소 검증",
"HeaderNav.link.advancedSettings": "고급 설정",
"HeaderNav.link.emailTemplates": "이메일 템플릿",
"HeaderNav.link.providers": "프로바이더(Providers)",
@ -71,6 +78,7 @@
"PopUpForm.Email.validation_email.options.message.placeholder": "<p>이 링크를 클릭하고 계정을 확인하세요.</p>",
"PopUpForm.Email.validation_email.options.object.placeholder": "%APP_NAME%의 이메일 주소를 확인하세요.",
"PopUpForm.Providers.callback.placeholder": "TEXT",
"PopUpForm.Providers.discord.providerConfig.redirectURL": "Discord 애플리케이션 구성에 추가 할 리다이렉트 URL",
"PopUpForm.Providers.enabled.description": "사용하지 않을 경우 이 프로바이더(provider) 기능을 이용할 수 없습니다.",
"PopUpForm.Providers.enabled.label": "사용",
"PopUpForm.Providers.facebook.providerConfig.redirectURL": "Facebook 애플리케이션 구성에 추가 할 리다이렉트 URL",
@ -80,6 +88,7 @@
"PopUpForm.Providers.key.label": "클라이언트 ID(Client ID)",
"PopUpForm.Providers.key.placeholder": "텍스트",
"PopUpForm.Providers.linkedin2.providerConfig.redirectURL": "Linkedin",
"PopUpForm.Providers.microsoft.providerConfig.redirectURL": "Microsoft 애플리케이션 구성에 추가 할 리다이렉트 URL",
"PopUpForm.Providers.redirectURL.front-end.label": "프론트엔드 애플리케이션 리다이렉트 URL",
"PopUpForm.Providers.secret.label": "클라이언트 시크릿(Client Secret)",
"PopUpForm.Providers.secret.placeholder": "텍스트",
@ -91,6 +100,7 @@
"PopUpForm.header.edit.providers": "프로바이더(Provider) 설정",
"PopUpForm.inputSelect.providers.label": "프로바이더(provider) 선택",
"components.Input.error.password.length": "패스워드가 너무 짧습니다.",
"notification.error.delete": "항목을 삭제하는데 에러가 발생했습니다.",
"notification.error.fetch": "데이터를 가져오는데 에러가 발생했습니다.",
"notification.error.fetchUser": "사용자를 가져오는데 에러가 발생했습니다.",
@ -99,4 +109,4 @@
"notification.success.submit": "설정을 업데이트했습니다.",
"plugin.description.long": "JWT 기반의 인증 프로세스로 API를 보호하세요. 이 플러그인에서 사용자 그룹간 권한을 관리할 수 있는 ACL 전략도 설정할 수 있습니다.",
"plugin.description.short": "JWT 기반의 인증 프로세스로 API를 보호하세요."
}
}

View File

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