jekyll-baserow-headless-cms 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.claude/settings.json +12 -0
- data/.mcp.json +68 -0
- data/.rspec +3 -0
- data/.rubocop.yml +87 -0
- data/CHANGELOG.md +38 -0
- data/Gemfile +10 -0
- data/LICENSE +21 -0
- data/README.md +291 -0
- data/Rakefile +26 -0
- data/docs/EXAMPLES_AND_CONFIGURATION.md +407 -0
- data/docs/architecture.excalidraw +3979 -0
- data/docs/architecture.png +0 -0
- data/docs/architecture.svg +5 -0
- data/docs/templates/github-actions_baserow-sync.yml +61 -0
- data/lib/jekyll-baserow-headless-cms.rb +14 -0
- data/lib/jekyll_baserow_headless_cms/baserow_client.rb +106 -0
- data/lib/jekyll_baserow_headless_cms/data_organizers.rb +249 -0
- data/lib/jekyll_baserow_headless_cms/field_extractors.rb +182 -0
- data/lib/jekyll_baserow_headless_cms/generator.rb +178 -0
- data/lib/jekyll_baserow_headless_cms/version.rb +5 -0
- metadata +189 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# Examples & Configuration Reference
|
|
2
|
+
|
|
3
|
+
This document provides detailed examples and configuration reference for jekyll-baserow-headless-cms.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Examples](#examples)
|
|
8
|
+
- [Projects Table](#projects-table)
|
|
9
|
+
- [Services Table](#services-table)
|
|
10
|
+
- [Testimonials Table](#testimonials-table)
|
|
11
|
+
- [Skills Table](#skills-table)
|
|
12
|
+
- [Configuration Reference](#configuration-reference)
|
|
13
|
+
- [Collection Options](#collection-options)
|
|
14
|
+
- [Organizer Types](#organizer-types)
|
|
15
|
+
- [Field Types](#field-types)
|
|
16
|
+
- [Field Configuration](#field-configuration)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
### Projects Table
|
|
23
|
+
|
|
24
|
+
Perfect for portfolios and case studies.
|
|
25
|
+
|
|
26
|
+
**Baserow Table Structure:**
|
|
27
|
+
|
|
28
|
+
| Field | Type | Description |
|
|
29
|
+
|-------|------|-------------|
|
|
30
|
+
| Name | Single line text | Project name |
|
|
31
|
+
| Description | Long text | Project description |
|
|
32
|
+
| Image | File | Cover image |
|
|
33
|
+
| Tags | Multiple select | Technologies used |
|
|
34
|
+
| URL | URL | Live project link |
|
|
35
|
+
| GitHub | URL | Repository link |
|
|
36
|
+
| Featured | Boolean | Show on homepage |
|
|
37
|
+
| Order | Number | Display order |
|
|
38
|
+
|
|
39
|
+
**Configuration:**
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
baserow:
|
|
43
|
+
collections:
|
|
44
|
+
projects:
|
|
45
|
+
table_env: BASEROW_PROJECTS_TABLE
|
|
46
|
+
data_file: baserow_projects.yml
|
|
47
|
+
organizer: simple_list
|
|
48
|
+
sort_by: order
|
|
49
|
+
fields:
|
|
50
|
+
- { name: Name, type: text }
|
|
51
|
+
- { name: Description, type: long_text }
|
|
52
|
+
- { name: Image, type: file }
|
|
53
|
+
- { name: Tags, type: multi_select }
|
|
54
|
+
- { name: URL, type: url }
|
|
55
|
+
- { name: GitHub, type: url, key: github_url }
|
|
56
|
+
- { name: Featured, type: boolean }
|
|
57
|
+
- { name: Order, type: number }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Template Usage:**
|
|
61
|
+
|
|
62
|
+
```liquid
|
|
63
|
+
{% for project in site.data.baserow_projects %}
|
|
64
|
+
{% if project.featured %}
|
|
65
|
+
<article class="project-card">
|
|
66
|
+
{% if project.image.first %}
|
|
67
|
+
<img src="{{ project.image.first.url }}" alt="{{ project.title }}" />
|
|
68
|
+
{% endif %}
|
|
69
|
+
<h3>{{ project.title }}</h3>
|
|
70
|
+
<p>{{ project.description }}</p>
|
|
71
|
+
<div class="tags">
|
|
72
|
+
{% for tag in project.tags %}
|
|
73
|
+
<span class="tag">{{ tag }}</span>
|
|
74
|
+
{% endfor %}
|
|
75
|
+
</div>
|
|
76
|
+
<div class="links">
|
|
77
|
+
{% if project.url %}<a href="{{ project.url }}">View Project</a>{% endif %}
|
|
78
|
+
{% if project.github_url %}<a href="{{ project.github_url }}">GitHub</a>{% endif %}
|
|
79
|
+
</div>
|
|
80
|
+
</article>
|
|
81
|
+
{% endif %}
|
|
82
|
+
{% endfor %}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### Services Table
|
|
88
|
+
|
|
89
|
+
Ideal for freelancers and agencies.
|
|
90
|
+
|
|
91
|
+
**Baserow Table Structure:**
|
|
92
|
+
|
|
93
|
+
| Field | Type | Description |
|
|
94
|
+
|-------|------|-------------|
|
|
95
|
+
| Name | Single line text | Service name |
|
|
96
|
+
| Description | Long text | Service description |
|
|
97
|
+
| Icon | Single select | Icon identifier (e.g., "code", "design") |
|
|
98
|
+
| Price | Single line text | Pricing information |
|
|
99
|
+
| Features | Long text | Key features (bullet points) |
|
|
100
|
+
| Category | Single select | Service category |
|
|
101
|
+
| Order | Number | Display order |
|
|
102
|
+
|
|
103
|
+
**Configuration:**
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
baserow:
|
|
107
|
+
collections:
|
|
108
|
+
services:
|
|
109
|
+
table_env: BASEROW_SERVICES_TABLE
|
|
110
|
+
data_file: baserow_services.yml
|
|
111
|
+
organizer: grouped_by
|
|
112
|
+
group_by: category
|
|
113
|
+
sort_by: order
|
|
114
|
+
fields:
|
|
115
|
+
- { name: Name, type: text }
|
|
116
|
+
- { name: Description, type: long_text }
|
|
117
|
+
- { name: Icon, type: single_select }
|
|
118
|
+
- { name: Price, type: text }
|
|
119
|
+
- { name: Features, type: long_text }
|
|
120
|
+
- { name: Category, type: single_select }
|
|
121
|
+
- { name: Order, type: number }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Template Usage:**
|
|
125
|
+
|
|
126
|
+
```liquid
|
|
127
|
+
{% for category in site.data.baserow_services %}
|
|
128
|
+
<section class="service-category">
|
|
129
|
+
<h2>{{ category[0] }}</h2>
|
|
130
|
+
{% for service in category[1] %}
|
|
131
|
+
<div class="service-card">
|
|
132
|
+
<i class="icon-{{ service.icon }}"></i>
|
|
133
|
+
<h3>{{ service.title }}</h3>
|
|
134
|
+
<p>{{ service.description }}</p>
|
|
135
|
+
<p class="price">{{ service.price }}</p>
|
|
136
|
+
</div>
|
|
137
|
+
{% endfor %}
|
|
138
|
+
</section>
|
|
139
|
+
{% endfor %}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### Testimonials Table
|
|
145
|
+
|
|
146
|
+
Build trust with client testimonials.
|
|
147
|
+
|
|
148
|
+
**Baserow Table Structure:**
|
|
149
|
+
|
|
150
|
+
| Field | Type | Description |
|
|
151
|
+
|-------|------|-------------|
|
|
152
|
+
| Quote | Single line text | Testimonial text |
|
|
153
|
+
| Author | Single line text | Client name |
|
|
154
|
+
| Role | Single line text | Client's job title |
|
|
155
|
+
| Company | Single line text | Client's company |
|
|
156
|
+
| Avatar | File | Client photo |
|
|
157
|
+
| Rating | Rating | Star rating (1-5) |
|
|
158
|
+
| Featured | Boolean | Show on homepage |
|
|
159
|
+
| Date | Date | Testimonial date |
|
|
160
|
+
|
|
161
|
+
**Configuration:**
|
|
162
|
+
|
|
163
|
+
```yaml
|
|
164
|
+
baserow:
|
|
165
|
+
collections:
|
|
166
|
+
testimonials:
|
|
167
|
+
table_env: BASEROW_TESTIMONIALS_TABLE
|
|
168
|
+
data_file: baserow_testimonials.yml
|
|
169
|
+
organizer: simple_list
|
|
170
|
+
sort_by: date
|
|
171
|
+
sort_order: desc
|
|
172
|
+
fields:
|
|
173
|
+
- { name: Quote, type: text, key: title }
|
|
174
|
+
- { name: Author, type: text }
|
|
175
|
+
- { name: Role, type: text }
|
|
176
|
+
- { name: Company, type: text }
|
|
177
|
+
- { name: Avatar, type: file }
|
|
178
|
+
- { name: Rating, type: rating }
|
|
179
|
+
- { name: Featured, type: boolean }
|
|
180
|
+
- { name: Date, type: date }
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Template Usage:**
|
|
184
|
+
|
|
185
|
+
```liquid
|
|
186
|
+
<section class="testimonials">
|
|
187
|
+
{% for testimonial in site.data.baserow_testimonials %}
|
|
188
|
+
{% if testimonial.featured %}
|
|
189
|
+
<blockquote class="testimonial">
|
|
190
|
+
<div class="stars">
|
|
191
|
+
{% for i in (1..testimonial.rating) %}
|
|
192
|
+
<span class="star">★</span>
|
|
193
|
+
{% endfor %}
|
|
194
|
+
</div>
|
|
195
|
+
<p>"{{ testimonial.title }}"</p>
|
|
196
|
+
<footer>
|
|
197
|
+
{% if testimonial.avatar.first %}
|
|
198
|
+
<img src="{{ testimonial.avatar.first.url }}" alt="{{ testimonial.author }}" class="avatar" />
|
|
199
|
+
{% endif %}
|
|
200
|
+
<cite>
|
|
201
|
+
<strong>{{ testimonial.author }}</strong>
|
|
202
|
+
<span>{{ testimonial.role }}, {{ testimonial.company }}</span>
|
|
203
|
+
</cite>
|
|
204
|
+
</footer>
|
|
205
|
+
</blockquote>
|
|
206
|
+
{% endif %}
|
|
207
|
+
{% endfor %}
|
|
208
|
+
</section>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### Skills Table
|
|
214
|
+
|
|
215
|
+
Showcase your technical expertise.
|
|
216
|
+
|
|
217
|
+
For grouping skills by category, model it in Baserow with two tables: a **Skills** table
|
|
218
|
+
linked to a **Categories** table (via a *Link to table* field), and lookup fields on Skills
|
|
219
|
+
that pull in the category's name, icon and order. This mirrors how the `items_by_category`
|
|
220
|
+
organizer worked with Notion rollups.
|
|
221
|
+
|
|
222
|
+
**Baserow Table Structure (Skills)** (`items_by_category` reads these exact field names — see
|
|
223
|
+
[`items_by_category`](#organizer-types) for details):
|
|
224
|
+
|
|
225
|
+
| Field | Type | Description |
|
|
226
|
+
|-------|------|-------------|
|
|
227
|
+
| Name | Single line text | Skill name |
|
|
228
|
+
| Category | Lookup (via link to Categories) | Skill category (Backend, Frontend, etc.) |
|
|
229
|
+
| Icon | Lookup (via link to Categories) | Category icon |
|
|
230
|
+
| Color | Lookup | Skill color |
|
|
231
|
+
| Category Order | Lookup (via link to Categories) | Display order of the category |
|
|
232
|
+
| Level | Number | Proficiency level |
|
|
233
|
+
| Years | Number | Years of experience |
|
|
234
|
+
| Featured | Boolean | Highlight this skill |
|
|
235
|
+
| Order | Number | Display order within category |
|
|
236
|
+
|
|
237
|
+
**Configuration:**
|
|
238
|
+
|
|
239
|
+
```yaml
|
|
240
|
+
baserow:
|
|
241
|
+
collections:
|
|
242
|
+
skills:
|
|
243
|
+
table_env: BASEROW_SKILLS_TABLE
|
|
244
|
+
data_file: baserow_skills.yml
|
|
245
|
+
organizer: items_by_category
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Template Usage:**
|
|
249
|
+
|
|
250
|
+
```liquid
|
|
251
|
+
{% for category in site.data.baserow_skills %}
|
|
252
|
+
<section class="skill-category">
|
|
253
|
+
<h3>
|
|
254
|
+
<i class="{{ category[1].icon }}"></i>
|
|
255
|
+
{{ category[1].title }}
|
|
256
|
+
</h3>
|
|
257
|
+
<div class="skills-grid">
|
|
258
|
+
{% for item in category[1].items %}
|
|
259
|
+
<div class="skill" style="--skill-color: {{ item.color }}">
|
|
260
|
+
<span class="skill-name">
|
|
261
|
+
{{ item.name }}
|
|
262
|
+
{% if item.featured %}<span class="badge">★</span>{% endif %}
|
|
263
|
+
</span>
|
|
264
|
+
<div class="skill-bar">
|
|
265
|
+
<div class="skill-level" style="width: {{ item.level }}%"></div>
|
|
266
|
+
</div>
|
|
267
|
+
<span class="skill-years">{{ item.years }} years</span>
|
|
268
|
+
</div>
|
|
269
|
+
{% endfor %}
|
|
270
|
+
</div>
|
|
271
|
+
</section>
|
|
272
|
+
{% endfor %}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Configuration Reference
|
|
278
|
+
|
|
279
|
+
### Collection Options
|
|
280
|
+
|
|
281
|
+
| Option | Type | Required | Description |
|
|
282
|
+
|--------|------|----------|-------------|
|
|
283
|
+
| `table_env` | String | Yes | Environment variable containing the Baserow table ID |
|
|
284
|
+
| `data_file` | String | Yes | Output filename in `_data/` directory |
|
|
285
|
+
| `organizer` | String | No | Data organization method (default: `simple_list`) |
|
|
286
|
+
| `sort_by` | String | No | Field key to sort by |
|
|
287
|
+
| `sort_order` | String | No | `asc` (default) or `desc` |
|
|
288
|
+
| `group_by` | String | No | Field to group by (for `grouped_by` organizer) |
|
|
289
|
+
| `fields` | Array | Yes* | Field mapping configuration (*not used by `items_by_category`, which reads fixed field names) |
|
|
290
|
+
|
|
291
|
+
### Organizer Types
|
|
292
|
+
|
|
293
|
+
#### `simple_list` (default)
|
|
294
|
+
|
|
295
|
+
Returns an array of items sorted by the specified field.
|
|
296
|
+
|
|
297
|
+
```yaml
|
|
298
|
+
organizer: simple_list
|
|
299
|
+
sort_by: order
|
|
300
|
+
sort_order: asc
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
#### `items_by_category`
|
|
304
|
+
|
|
305
|
+
Groups items by their category. Useful for skills, products, team members, or any categorized content.
|
|
306
|
+
|
|
307
|
+
```yaml
|
|
308
|
+
organizer: items_by_category
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
> **Note:** unlike the other organizers, `items_by_category` does **not** use the `fields:`
|
|
312
|
+
> list — it reads a fixed set of field names directly from each row. Your table must use
|
|
313
|
+
> these exact names:
|
|
314
|
+
>
|
|
315
|
+
> | Field | Type | Used for |
|
|
316
|
+
> |-------|------|----------|
|
|
317
|
+
> | `Name` | Text | Item name |
|
|
318
|
+
> | `Category` | Lookup | Category name (groups items together) |
|
|
319
|
+
> | `Icon` | Lookup | Category icon |
|
|
320
|
+
> | `Color` | Lookup | Item color |
|
|
321
|
+
> | `Category Order` | Lookup | Category display order |
|
|
322
|
+
> | `Level` | Number | Item level |
|
|
323
|
+
> | `Years` | Number | Item years |
|
|
324
|
+
> | `Featured` | Boolean | Item featured flag |
|
|
325
|
+
> | `Order` | Number | Item display order within its category |
|
|
326
|
+
>
|
|
327
|
+
> `Category`, `Icon`, `Color` and `Category Order` are typically lookup fields pulling from a
|
|
328
|
+
> *Categories* table via a *Link to table* field, so all items in the same category share the
|
|
329
|
+
> same icon/order.
|
|
330
|
+
|
|
331
|
+
Output structure:
|
|
332
|
+
```yaml
|
|
333
|
+
Backend:
|
|
334
|
+
title: Backend
|
|
335
|
+
category: Backend
|
|
336
|
+
subcategory: null
|
|
337
|
+
icon: code
|
|
338
|
+
order: 1
|
|
339
|
+
items:
|
|
340
|
+
- name: Ruby
|
|
341
|
+
level: 90
|
|
342
|
+
years: 10
|
|
343
|
+
description: null
|
|
344
|
+
icon: null
|
|
345
|
+
color: blue
|
|
346
|
+
featured: true
|
|
347
|
+
order: 1
|
|
348
|
+
id: 42
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### `grouped_by`
|
|
352
|
+
|
|
353
|
+
Groups items by a specified field.
|
|
354
|
+
|
|
355
|
+
```yaml
|
|
356
|
+
organizer: grouped_by
|
|
357
|
+
group_by: category
|
|
358
|
+
sort_by: order
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
#### `nested`
|
|
362
|
+
|
|
363
|
+
Creates a hierarchical tree structure based on parent-child relationships.
|
|
364
|
+
|
|
365
|
+
```yaml
|
|
366
|
+
organizer: nested
|
|
367
|
+
parent_field: parent_id
|
|
368
|
+
sort_by: order
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Field Types
|
|
372
|
+
|
|
373
|
+
| Type | Baserow Field | Output |
|
|
374
|
+
|------|-----------------|--------|
|
|
375
|
+
| `text` | Single line text | String |
|
|
376
|
+
| `long_text` | Long text | String |
|
|
377
|
+
| `number` | Number | Integer/Float |
|
|
378
|
+
| `boolean` | Boolean | Boolean |
|
|
379
|
+
| `date` | Date | ISO 8601 string |
|
|
380
|
+
| `single_select` | Single select | String |
|
|
381
|
+
| `multi_select` | Multiple select | Array of strings |
|
|
382
|
+
| `url` | URL | String |
|
|
383
|
+
| `email` | Email | String |
|
|
384
|
+
| `phone_number` | Phone number | String |
|
|
385
|
+
| `file` | File | Array of file objects |
|
|
386
|
+
| `rating` | Rating | Integer |
|
|
387
|
+
| `count` | Count | Integer |
|
|
388
|
+
| `link_row` | Link to table | Array of `{ id, name }` objects |
|
|
389
|
+
| `lookup` | Lookup | Single value or array from a linked table |
|
|
390
|
+
| `formula` | Formula (scalar) | Computed value |
|
|
391
|
+
| `formula_array` | Formula (array of) | Single value or array of values |
|
|
392
|
+
| `created_on` | Created on | ISO 8601 string |
|
|
393
|
+
| `last_modified` | Last modified | ISO 8601 string |
|
|
394
|
+
|
|
395
|
+
### Field Configuration
|
|
396
|
+
|
|
397
|
+
```yaml
|
|
398
|
+
fields:
|
|
399
|
+
- name: "Field Name" # Name in Baserow (required)
|
|
400
|
+
type: text # Field type (required)
|
|
401
|
+
key: custom_key # Output key (optional, defaults to snake_case)
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
> **Important:** `simple_list` and `grouped_by` drop any item whose `title` key is empty —
|
|
405
|
+
> they treat `title` as the record's identifier (see [`extract_all`](#organizer-types)). If
|
|
406
|
+
> your primary field isn't named `Name` or `Title` (e.g. `Quote` for a testimonial), give it
|
|
407
|
+
> `key: title` explicitly, or items will silently disappear from the output.
|