1 | <p align="center">
|
2 | <img src="./assets/logo.svg" height="200">
|
3 | </p>
|
4 |
|
5 | # Wombat
|
6 | Simple open-source flat-file serverless Content Management Framework (headless-CMS) to build powerful API effortlessly.
|
7 |
|
8 | ## Features
|
9 | - **Simple** - Designed to replace Wordpress in building simple company / product / event pages
|
10 | - **Fast and lightweight** - Serverless oriented, no framework, no database or other system-wide requirements
|
11 | - **Two types of data** - Unlike Contentful or Strapi, offers not only items collection, but also single entities, that can be used to build pages or store configuration
|
12 | - **Full internationalization** - Every piece content is assigned to one language, so you have complete freedom in customizing it
|
13 | - **No strict schema** - Do you need each item within a content type to do be different and have a different structure for each language? No problem, sky is the limit!
|
14 | - **No Admin Panel** - You are not limited by the UI or poor UX, just you and bunch of JSON and Markdown files
|
15 | - **Front-end agnostic** - Simple REST API can be used by any application
|
16 |
|
17 |
|
18 | ## Setup
|
19 | 1. Add Wombat as dependecy `yarn add @snowdog/wombat`
|
20 | 2. Create content following [Content structure](#content-structure) description.
|
21 | 2. Add `"dev": "wombat dev"` to `package.json` scripts section
|
22 | 3. Run `yarn dev` and enjoy working with your new API
|
23 |
|
24 | ## Serverless deployment
|
25 | This guide is for [ZEIT Now](https://zeit.co/docs/v2/deployments/official-builders/node-js-now-node/), but setting up any other serverless env looks simillar.
|
26 |
|
27 | 1. In `package.json` add automatic DB building after installing dependecies
|
28 | ```
|
29 | "scripts": {
|
30 | "postinstall": "wombat build",
|
31 | "dev": "wombat dev"
|
32 | }
|
33 | ```
|
34 | 2. Define new builds and routes in `now.json` acording to [the example](./examples/now/now.json)
|
35 | 3. Copy [collection.js](./examples/now/collection.js) and [entity.js](./examples/now/entity.js) from examples
|
36 | 4. Deploy your app via `now`
|
37 |
|
38 | ## Config options
|
39 | * `defaultLang` (default `en`) - Fallback language when request is send without `lang` query param.
|
40 | * `port` (default `3000`, only for development purpouses) Port used by the web server to listen for requests.
|
41 |
|
42 | ## Content structure
|
43 | All content is kept in `/content` directory.
|
44 | Inside you need to define supported languages. For example, we want to have content just in English, so it will be `/content/en`.
|
45 |
|
46 | Wombat supports two data types:
|
47 | ### Collections
|
48 | Designed to store sets of similar data, like blog posts, authors, job offers etc.
|
49 | - Collections are stored in `collection` directory inside each language.
|
50 | - Each collection and item of collection needs to be added as a directory.
|
51 | - Every property of an item collection needs to be a separate JSON or Markdown file.
|
52 |
|
53 | ### Entities
|
54 | Created to keep a single object like a landing page content or global configuration.
|
55 | - Entities are stored in `entity` directory inside each language.
|
56 | - Each entity needs to be added as a directory.
|
57 | - Every property of entity needs to be a separate JSON or Markdown file.
|
58 | - You can define the relation between entity and collection.
|
59 |
|
60 | ### How to define a relation between entity and collection?
|
61 | Create new JSON file inside entity directory to define relation:
|
62 | ```js
|
63 | {
|
64 | "query": {
|
65 | "name": "collectionName", // (required) collection name
|
66 | "sortBy": "title", // prop name used for sorting
|
67 | "sort": "asc", // `desc` is default - `sortBy` required to use it
|
68 | "limit": 2, // limit numer of returned items
|
69 | "page": 1, // page number
|
70 | "perPage": 100, // numer of items per page
|
71 | "items": ["award", "about", "partner"], // Array of collection items IDs. Items order is preserved.
|
72 | "props": ["id", "content"] // return only selected object props
|
73 | }
|
74 | }
|
75 | ```
|
76 |
|
77 | ### Example content tree
|
78 | ```
|
79 | content
|
80 | └── en
|
81 | ├── collection
|
82 | | └── blog
|
83 | | └── why-wombat-poop-is-cube
|
84 | | | ├── content.md
|
85 | | | ├── featured-image.json
|
86 | | | └── title.json
|
87 | | └── things-you-dont-know-about-wombats
|
88 | | ├── content.md
|
89 | | ├── featured-image.json
|
90 | | ├── form-config.json
|
91 | | └── title.json
|
92 | └── entity
|
93 | └── home
|
94 | ├── blog-posts.json
|
95 | ├── about.md
|
96 | └── hero-banner.json
|
97 | ```
|
98 | ## API
|
99 | ### `/entity`
|
100 | Retrieve an entity item.
|
101 |
|
102 | **Example:**
|
103 | To get `home` entity send request to `/entity?name=home`.
|
104 |
|
105 | **URL params:**
|
106 | - `name` - (required) Name of entity
|
107 | - `lang` - Return content in given lang.
|
108 |
|
109 | ### `/collection`
|
110 | Retrieve the whole collection as array.
|
111 |
|
112 | **Examples:**
|
113 | #### Whole collection
|
114 | ```
|
115 | /collection?name=blog
|
116 | ```
|
117 |
|
118 | #### Whole collection, but only title and content
|
119 | ```
|
120 | /collection?name=blog&props=title,title
|
121 | ```
|
122 |
|
123 | #### Only items selected by ID
|
124 | ```
|
125 | /collection?name=blog&items=why-wombat-poop-is-cube,things-you-dont-know-about-wombats
|
126 | ```
|
127 |
|
128 | #### Two items from collection sorted by title descending
|
129 | ```
|
130 | /collection?name=blog&limit=2&sortBy=title&sort=desc
|
131 | ```
|
132 |
|
133 | #### Items from second page, up to five per page
|
134 | ```
|
135 | /collection?name=blog&page=2&perPage=5
|
136 | ```
|
137 |
|
138 | **URL params:**
|
139 | - `name` - (required) Name of collection.
|
140 | - `lang` - Return content in given lang.
|
141 | - `sortBy` - Prop name used for sorting.
|
142 | - `sort` - `desc` is default - `sortBy` required to use it.
|
143 | - `limit` - Limit numer of returned items.
|
144 | - `page` - Page number.
|
145 | - `perPage` - Numer of items per page.
|
146 | - `items` - Comma separated list of collection items IDs. Items order is preserved.
|
147 | - `props` - Comma separated list of selected object props, GraphQL-like.
|