回到 Canner

CannerTypes (Schema)

當您要開始撰寫 CMS schema 時,您需要 CannerTypes 的程式庫來宣告您的 CMS 架構。

其主要支援 methods 為:

CannerTypes.endpoint()

endpoint 為設定資料來源,只在第一層的 key 有效或是直接利用 CannerTypes.endpoint 設定預設的來源。

CannerTypes.endpoint(name: string, config: any);

Firbase Realtime Database endpoint

CannerTypes.endpoint('firebase');

Firebase Firestore endpoint

CannerTypes.endpoint('firebase.firestore.admin');

範例

如果你的資料統一來自同一個來源

1
2
3
4
5
6
7
// 預設所有的資料來自於此 endpoint
CannerTypes.endpoint('endpointName', endpointConfig);

const home = CannerTypes.object({...fields});
const info = CannerTypes.object({...fields});

export default CannerTypes.object({home, info});

每個 entity 來自不同的資料源

// 每個 enitiy 可以有自己的資料來源
const home = CannerTypes.object({...fields}).endpoint('endpointName', endpointConfig);
const info = CannerTypes.object({...fields}).endpoint('endpointName2', endpointConfig2);

子資料集可以來自不同的資料源

1
2
3
4
5
6
7
// 預設
CannerTypes.endpoint('endpointName', endpointConfig);

// home 會使用預設的 endpoint
const home = CannerTypes.object({...fields});
// info 使用自己的 endpoint
const info = CannerTypes.object({...fields}).endpoint('endpointName2', endpointConfig2);

CannerTypes.type()

type 類的方法,用來創造特定資料型別的 schema,目前共有六種: string, boolean, number, array, object, relation

string, boolean, number type

宣告資料型別為字串、布林、數字。

var name = CannerTypes.string();
var bool = CannerTypes.boolean()
var num = CannerTypes.number()

array type

宣告資料型別為陣列。

var name = CannerTypes.string();
CannerTypes.array({name: name})

object type

宣告資料型別為物件。

var name = CannerTypes.string();
CannerTypes.object({name: name})

relation type

宣告資料型別為關聯式欄位。

var name = CannerTypes.relation(relationConfig)
.ui(ui);  'one' || 'list'

relation config

Relation type 有四種 relationship: ManyToOneOneToMany.idListOneToMany.idMapOnetoMany.idForeignKey

manyToOne

// 宣告一個叫 `categoryRel` 的 manyToOne 關聯資料欄位,對應到 categories schema
const categoryRel = CannerTypes.relation({
  relationTo: 'categories',
  relationship: 'manyToOne'
})
// 每一個 post 都有一個 category,post 的 `categoryRel` 欄位會存放對應的 category id
categoryRel: id

oneToMany.idList

1
2
3
4
5
// 宣告一個叫 `tagRel` 的 OneToMany 且為 `List` 形式的關聯資料欄位,對應到 tags schema   
const tagRel = CannerTypes.relation({
  relationTo: 'tags',
  relationship: 'oneToMany.idList'
})
// 每個文章都有多個 tags,`tagRel` 欄位會以 List 的形式存放 tag id
tagRel: [id1, id2, id3]

onetoMany.idMap

1
2
3
4
5
// 宣告一個叫 `tagRel` 的 OneToMany 且為 `Map` 形式的關聯資料欄位,對應到 tags schema   
const tagRel = CannerTypes.relation({
  relationTo: 'tags',
  relationship: 'oneToMany.idMap'
})
1
2
3
4
5
6
// 每個文章都有多個 tags,`tagRel` 欄位會以 Map 型別且 value 為 `true` 的形式存放
tagRel: {
  id1: true,
  id2: true,
  id3: true
}

oneToMany.idMap 可以使用 pickOne 去儲存特定的 value 欄位,例如:

1
2
3
4
5
const tagRel = CannerTypes.relation({
  relationTo: 'tags',
  relationship: 'oneToMany.idMap',
  pickeOne: 'name'
})
1
2
3
4
5
6
// `tagRel` 欄位會以 Map 且 value 為 tag name 的形式存放
tagRel: {
  id1: 'dog',
  id2: 'cat',
  id3: 'elephant'
}

onetoMany.idForeignKey

透過 Foreign key 的宣告,可以讓在你在 CMS 中從直接修改對應的 foreign key 資料。

1
2
3
4
5
6
// 宣告 category 有一個 foreign key `postRef` 關聯到 post schema 的資料欄位
const postRel = CannerTypes.relation({
  relationTo: 'posts',
  relationship: 'oneToMany.idForeignKey',
  foreignKey: 'category'
}).ui('list')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// categories & posts 資料欄位
// 實際 category 資料中並不會真的有 postRel 欄位,但於 Canner CMS 中 posts 會有一個 postRef UI 可以修改該 category 對應的 posts

categories: [{
  _id: 'categoryId',
  name: 'category1'
}],

posts: [{
  _id: 'postId',
  name: 'post1',
  category: 'categoryId' // this is the foreignKey
}, {
  _id: 'postId2',
  name: 'post2',
  category: 'categoryId' // this is the foreignKey
}],

CannerTypes.title()

設定在後台顯示的欄位名稱。

CannerTypes.title(string)

CannerTypes.description()

設定在後台顯示的欄位描述。

CannerTypes.description(string)

CannerTypes.ui()

設定在後台顯示的介面。

CannerTypes.ui(string)

CannerTypes.uiParams()

彈性設定介面的樣式調整。每個 ui 會有不同的 uiParams 可以調整。

CannerTypes.uiParams({
  [string]: any
})

CannerTypes.addFilter()

popup UI 可以設定 Filter,產生篩選資料的功能

addFilter(key: string, label: string, filterConfig: any)
// text search
.addFilter('name', '類別名稱', {
   type: 'text'
})

// number query
.addFilter('price', '價格', {
   type: 'numberRange'
})

// custom query with select
.addFilter('orderStatus', '訂單狀態', {
    type: "select",
    options: [
       {text: '新訂單', condition: {_eq: 'new'}},
       {text: '舊訂單', condition: {_eq: 'old'}}
    ]
  })

CannerTypes.addSort()

popup UI 可以設定 Sort,產生排序資料的功能

addSort(key: string, label: string)

下一步