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
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ea0b75ace4c5a6878f34fc412bec22347460a17f4dcbc0e2d3088e454c695a3f
|
|
4
|
+
data.tar.gz: 9d3fb852f8211644eb4fbbf5e7812035e925b4743756861a69a22ebd980e17cb
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 789951bea1a8165ddd6f545ef66c3105f202abe2e548d43b90e6355bc80c8dbd23a063779915ac18eae8bf30ddc29ae0626e48e4b49334f8cec125bc16ef97ab
|
|
7
|
+
data.tar.gz: 1640cbd21456c4bd7062ded704b13547eeeda1aef71e5a1a66282f384d53bd2c5f4edac27776063ff8e286403fd17731b79a997594bd4daf0c1b2bfd81f310c6
|
data/.mcp.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"github": {
|
|
4
|
+
"type": "http",
|
|
5
|
+
"url": "https://api.githubcopilot.com/mcp/",
|
|
6
|
+
"headers": {
|
|
7
|
+
"Authorization": "Bearer ${GITHUB_MCP_PAT}"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"context7": {
|
|
11
|
+
"type": "http",
|
|
12
|
+
"url": "https://mcp.context7.com/mcp",
|
|
13
|
+
"headers": {
|
|
14
|
+
"CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"chrome-devtools": {
|
|
18
|
+
"type": "stdio",
|
|
19
|
+
"command": "npx",
|
|
20
|
+
"args": ["chrome-devtools-mcp@latest"],
|
|
21
|
+
"env": {}
|
|
22
|
+
},
|
|
23
|
+
"figma-desktop": {
|
|
24
|
+
"type": "http",
|
|
25
|
+
"url": "http://127.0.0.1:3845/mcp"
|
|
26
|
+
},
|
|
27
|
+
"sentry": {
|
|
28
|
+
"type": "http",
|
|
29
|
+
"url": "https://mcp.sentry.dev/mcp"
|
|
30
|
+
},
|
|
31
|
+
"n8n-mcp-staging": {
|
|
32
|
+
"command": "npx",
|
|
33
|
+
"args": ["n8n-mcp"],
|
|
34
|
+
"env": {
|
|
35
|
+
"MCP_MODE": "stdio",
|
|
36
|
+
"LOG_LEVEL": "error",
|
|
37
|
+
"DISABLE_CONSOLE_OUTPUT": "true",
|
|
38
|
+
"N8N_API_URL": "https://n8n.staging.maxime-lenne.fr/",
|
|
39
|
+
"N8N_API_KEY": "${N8N_STAGING_API_KEY}"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"n8n-mcp-prod": {
|
|
43
|
+
"command": "npx",
|
|
44
|
+
"args": ["n8n-mcp"],
|
|
45
|
+
"env": {
|
|
46
|
+
"MCP_MODE": "stdio",
|
|
47
|
+
"LOG_LEVEL": "error",
|
|
48
|
+
"DISABLE_CONSOLE_OUTPUT": "true",
|
|
49
|
+
"N8N_API_URL": "https://n8n.maxime-lenne.fr/",
|
|
50
|
+
"N8N_API_KEY": "${N8N_PROD_API_KEY}"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"MCP_DOCKER": {
|
|
54
|
+
"command": "docker",
|
|
55
|
+
"args": ["mcp", "gateway", "run"]
|
|
56
|
+
},
|
|
57
|
+
"excalidraw-staging": {
|
|
58
|
+
"type": "http",
|
|
59
|
+
"url": "https://excalidraw.staging.maxime-lenne.fr/mcp"
|
|
60
|
+
},
|
|
61
|
+
"pencil": {
|
|
62
|
+
"type": "stdio",
|
|
63
|
+
"command": "/Applications/Pencil.app/Contents/Resources/app.asar.unpacked/out/mcp-server-darwin-arm64",
|
|
64
|
+
"args": ["--app", "desktop"],
|
|
65
|
+
"env": {}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-rspec
|
|
3
|
+
|
|
4
|
+
AllCops:
|
|
5
|
+
TargetRubyVersion: 2.7
|
|
6
|
+
NewCops: enable
|
|
7
|
+
SuggestExtensions: false
|
|
8
|
+
Exclude:
|
|
9
|
+
- 'vendor/**/*'
|
|
10
|
+
- 'spec/fixtures/**/*'
|
|
11
|
+
|
|
12
|
+
# Naming
|
|
13
|
+
Naming/FileName:
|
|
14
|
+
Exclude:
|
|
15
|
+
- 'lib/jekyll-baserow-headless-cms.rb'
|
|
16
|
+
|
|
17
|
+
# Gemspec
|
|
18
|
+
Gemspec/DevelopmentDependencies:
|
|
19
|
+
Enabled: false
|
|
20
|
+
|
|
21
|
+
# Metrics
|
|
22
|
+
Metrics/AbcSize:
|
|
23
|
+
Max: 35
|
|
24
|
+
|
|
25
|
+
Metrics/BlockLength:
|
|
26
|
+
Max: 35
|
|
27
|
+
Exclude:
|
|
28
|
+
- 'spec/**/*'
|
|
29
|
+
- '*.gemspec'
|
|
30
|
+
|
|
31
|
+
Metrics/MethodLength:
|
|
32
|
+
Max: 45
|
|
33
|
+
|
|
34
|
+
Metrics/ClassLength:
|
|
35
|
+
Max: 200
|
|
36
|
+
|
|
37
|
+
Metrics/ModuleLength:
|
|
38
|
+
Max: 250
|
|
39
|
+
|
|
40
|
+
Metrics/CyclomaticComplexity:
|
|
41
|
+
Max: 25
|
|
42
|
+
|
|
43
|
+
Metrics/PerceivedComplexity:
|
|
44
|
+
Max: 12
|
|
45
|
+
|
|
46
|
+
# Style
|
|
47
|
+
Style/Documentation:
|
|
48
|
+
Enabled: false
|
|
49
|
+
|
|
50
|
+
Style/StringLiterals:
|
|
51
|
+
EnforcedStyle: single_quotes
|
|
52
|
+
|
|
53
|
+
Style/FrozenStringLiteralComment:
|
|
54
|
+
Enabled: true
|
|
55
|
+
|
|
56
|
+
# Layout
|
|
57
|
+
Layout/LineLength:
|
|
58
|
+
Max: 120
|
|
59
|
+
Exclude:
|
|
60
|
+
- 'spec/**/*'
|
|
61
|
+
|
|
62
|
+
# Lint
|
|
63
|
+
Lint/DuplicateBranch:
|
|
64
|
+
Enabled: false
|
|
65
|
+
|
|
66
|
+
# RSpec
|
|
67
|
+
RSpec/ExampleLength:
|
|
68
|
+
Max: 25
|
|
69
|
+
|
|
70
|
+
RSpec/MultipleExpectations:
|
|
71
|
+
Max: 5
|
|
72
|
+
|
|
73
|
+
RSpec/NestedGroups:
|
|
74
|
+
Max: 4
|
|
75
|
+
|
|
76
|
+
RSpec/MultipleMemoizedHelpers:
|
|
77
|
+
Max: 10
|
|
78
|
+
|
|
79
|
+
RSpec/MessageSpies:
|
|
80
|
+
Enabled: false
|
|
81
|
+
|
|
82
|
+
RSpec/IndexedLet:
|
|
83
|
+
Enabled: false
|
|
84
|
+
|
|
85
|
+
# RSpec (Capybara-specific matcher rule, renamed under the RSpec department in rubocop-rspec 3.x)
|
|
86
|
+
RSpec/PredicateMatcher:
|
|
87
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-08-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial release of jekyll-baserow-headless-cms, adapted from
|
|
13
|
+
[jekyll-notion-cms](https://github.com/maxime-lenne/jekyll-notion-cms) to use
|
|
14
|
+
[Baserow](https://baserow.io) as the content source instead of Notion
|
|
15
|
+
- Configurable collections via `_config.yml`
|
|
16
|
+
- Support for Baserow field types:
|
|
17
|
+
- Text, Long text, Number, Boolean
|
|
18
|
+
- Date, Created on, Last modified
|
|
19
|
+
- Single select, Multiple select
|
|
20
|
+
- URL, Email, Phone number
|
|
21
|
+
- File, Rating, Count
|
|
22
|
+
- Link to table, Lookup, Formula
|
|
23
|
+
- Multiple data organizers:
|
|
24
|
+
- `simple_list` - Sorted array of items
|
|
25
|
+
- `items_by_category` - Items grouped by category (skills, products, etc.)
|
|
26
|
+
- `grouped_by` - Items grouped by a field
|
|
27
|
+
- `nested` - Hierarchical tree structure
|
|
28
|
+
- Automatic fallback to Jekyll collections
|
|
29
|
+
- Pagination support for large tables
|
|
30
|
+
- Data file caching to avoid unnecessary regeneration
|
|
31
|
+
- Comprehensive logging
|
|
32
|
+
- Support for self-hosted Baserow instances via `BASEROW_API_URL`
|
|
33
|
+
|
|
34
|
+
### Security
|
|
35
|
+
|
|
36
|
+
- Secure handling of Baserow API tokens via environment variables
|
|
37
|
+
|
|
38
|
+
[0.1.0]: https://github.com/maxime-lenne/jekyll-baserow-headless-cms/releases/tag/v0.1.0
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Maxime Lenne
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Jekyll Baserow Headless CMS
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://cdn.simpleicons.org/baserow" alt="Baserow" width="80" height="80" />
|
|
5
|
+
<img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/jekyll/jekyll-original.svg" alt="Jekyll" width="80" height="80" />
|
|
6
|
+
<img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/githubactions/githubactions-original-wordmark.svg" alt="Github Action" width="80" height="80" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<strong>Use Baserow as a headless CMS for your Jekyll static site</strong>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://badge.fury.io/rb/jekyll-baserow-headless-cms"><img src="https://badge.fury.io/rb/jekyll-baserow-headless-cms.svg" alt="Gem Version" /></a>
|
|
15
|
+
<a href="https://github.com/maxime-lenne/jekyll-baserow-headless-cms/actions/workflows/ci.yml"><img src="https://github.com/maxime-lenne/jekyll-baserow-headless-cms/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
16
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
A configurable Jekyll plugin that fetches content from [Baserow](https://baserow.io) tables and makes it available as Jekyll data files. Perfect for building landing pages, portfolios, blogs, and resumes with Baserow as your content management system.
|
|
22
|
+
|
|
23
|
+
This project is a Baserow-flavored sibling of [jekyll-notion-cms](https://github.com/maxime-lenne/jekyll-notion-cms) — same architecture and organizer system, adapted for Baserow's REST API and field model.
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- **Configurable Collections**: Define any number of Baserow table collections via `_config.yml`
|
|
28
|
+
- **Multiple Organizers**: Support for different data organization patterns (simple list, grouped, skills by category, nested)
|
|
29
|
+
- **Common Field Types**: Support for the main Baserow field types (text, number, date, select, multi-select, link to table, lookups, files, etc.)
|
|
30
|
+
- **Fallback System**: Automatic fallback to Jekyll collections when Baserow is unavailable
|
|
31
|
+
- **Pagination**: Handles large tables with automatic pagination
|
|
32
|
+
- **Caching**: Intelligent file caching to avoid unnecessary regenerations
|
|
33
|
+
- **Self-hosted friendly**: Works with baserow.io or any self-hosted Baserow instance via `BASEROW_API_URL`
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Architecture
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<img src="docs/architecture.png" alt="Jekyll Notion CMS Architecture" width="800" />
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
The diagram above shows how Jekyll Baserow Headless CMS integrates with your workflow:
|
|
43
|
+
|
|
44
|
+
1. **Content editing** in Baserow databases
|
|
45
|
+
2. **Change detection** via Baserow webhook
|
|
46
|
+
3. **Build trigger** through GitHub Actions workflow_dispatch
|
|
47
|
+
4. **Static site generation** with Jekyll + jekyll-baserow-headless-cms
|
|
48
|
+
5. **Deployment** to GitHub Pages (or any static host)
|
|
49
|
+
|
|
50
|
+
## Use Cases
|
|
51
|
+
|
|
52
|
+
### Landing Page
|
|
53
|
+
|
|
54
|
+
Build dynamic landing pages with content managed entirely in Baserow:
|
|
55
|
+
|
|
56
|
+
| Content Type | Baserow Table | Description |
|
|
57
|
+
|--------------|----------------|--------------|
|
|
58
|
+
| **Services** | Services | List your offerings with icons, descriptions, and pricing |
|
|
59
|
+
| **Testimonials** | Testimonials | Client reviews with photos, quotes, and ratings |
|
|
60
|
+
| **Team** | Team | Team member profiles with photos and bios |
|
|
61
|
+
| **FAQ** | FAQ | Frequently asked questions organized by category |
|
|
62
|
+
|
|
63
|
+
### Portfolio
|
|
64
|
+
|
|
65
|
+
Showcase your work with a portfolio powered by Baserow:
|
|
66
|
+
|
|
67
|
+
| Content Type | Baserow Table | Description |
|
|
68
|
+
|--------------|----------------|--------------|
|
|
69
|
+
| **Projects** | Projects | Portfolio pieces with images, descriptions, and links |
|
|
70
|
+
| **Skills** | Skills | Technical skills organized by category with proficiency levels |
|
|
71
|
+
| **Certifications** | Certifications | Professional certifications and badges |
|
|
72
|
+
|
|
73
|
+
### Blog
|
|
74
|
+
|
|
75
|
+
Run a full-featured blog with Baserow as your writing tool:
|
|
76
|
+
|
|
77
|
+
| Content Type | Baserow Table | Description |
|
|
78
|
+
|--------------|----------------|--------------|
|
|
79
|
+
| **Posts** | Blog | Articles with rich text, tags, and publication dates |
|
|
80
|
+
| **Categories** | Categories | Blog categories for organization |
|
|
81
|
+
| **Authors** | Authors | Author profiles for multi-author blogs |
|
|
82
|
+
|
|
83
|
+
### Resume / CV
|
|
84
|
+
|
|
85
|
+
Create a dynamic online resume:
|
|
86
|
+
|
|
87
|
+
| Content Type | Baserow Table | Description |
|
|
88
|
+
|--------------|----------------|--------------|
|
|
89
|
+
| **Experiences** | Experiences | Work history with dates, companies, and descriptions |
|
|
90
|
+
| **Education** | Education | Academic background and degrees |
|
|
91
|
+
| **Skills** | Skills | Technical and soft skills with proficiency |
|
|
92
|
+
| **Languages** | Languages | Language proficiencies |
|
|
93
|
+
|
|
94
|
+
## Installation
|
|
95
|
+
|
|
96
|
+
Add this line to your application's Gemfile:
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
gem 'jekyll-baserow-headless-cms'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
And then execute:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
bundle install
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Or install it yourself as:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
gem install jekyll-baserow-headless-cms
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Quick Start
|
|
115
|
+
|
|
116
|
+
### 1. Create a Baserow API token
|
|
117
|
+
|
|
118
|
+
1. Go to your Baserow workspace settings
|
|
119
|
+
2. Create a new **Database token** scoped to the workspace/database you want to sync
|
|
120
|
+
3. Copy the token
|
|
121
|
+
|
|
122
|
+
### 2. Configure Environment Variables
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
export BASEROW_TOKEN=your_database_token
|
|
126
|
+
export BASEROW_EXPERIENCES_TABLE=your_table_id
|
|
127
|
+
export BASEROW_BLOG_TABLE=your_blog_table_id
|
|
128
|
+
|
|
129
|
+
# Optional: only needed for a self-hosted Baserow instance
|
|
130
|
+
export BASEROW_API_URL=https://baserow.example.com
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 3. Add Configuration to `_config.yml`
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
baserow:
|
|
137
|
+
enabled: true
|
|
138
|
+
|
|
139
|
+
collections:
|
|
140
|
+
experiences:
|
|
141
|
+
table_env: BASEROW_EXPERIENCES_TABLE
|
|
142
|
+
data_file: baserow_experiences.yml
|
|
143
|
+
organizer: simple_list
|
|
144
|
+
sort_by: order
|
|
145
|
+
fields:
|
|
146
|
+
- { name: Title, type: text }
|
|
147
|
+
- { name: Company, type: text }
|
|
148
|
+
- { name: Start Date, type: date, key: start_date }
|
|
149
|
+
- { name: Current, type: boolean }
|
|
150
|
+
- { name: Tags, type: multi_select }
|
|
151
|
+
|
|
152
|
+
blog_posts:
|
|
153
|
+
table_env: BASEROW_BLOG_TABLE
|
|
154
|
+
data_file: baserow_blog_posts.yml
|
|
155
|
+
organizer: simple_list
|
|
156
|
+
sort_by: published_at
|
|
157
|
+
sort_order: desc
|
|
158
|
+
fields:
|
|
159
|
+
- { name: Title, type: text }
|
|
160
|
+
- { name: Slug, type: text }
|
|
161
|
+
- { name: Language, type: single_select }
|
|
162
|
+
- { name: Published At, type: date, key: published_at }
|
|
163
|
+
- { name: Status, type: single_select }
|
|
164
|
+
- { name: Excerpt, type: long_text }
|
|
165
|
+
- { name: Tags, type: multi_select }
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 4. Use Data in Templates
|
|
169
|
+
|
|
170
|
+
```liquid
|
|
171
|
+
{% for exp in site.data.baserow_experiences %}
|
|
172
|
+
<h3>{{ exp.title }}</h3>
|
|
173
|
+
<p>{{ exp.company }} - {{ exp.start_date }}</p>
|
|
174
|
+
{% endfor %}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Examples & Configuration
|
|
178
|
+
|
|
179
|
+
For detailed examples and configuration reference, see **[Examples & Configuration](docs/EXAMPLES_AND_CONFIGURATION.md)**.
|
|
180
|
+
|
|
181
|
+
**Examples included:**
|
|
182
|
+
- Projects Table (portfolio, case studies)
|
|
183
|
+
- Services Table (freelancers, agencies)
|
|
184
|
+
- Testimonials Table (client reviews)
|
|
185
|
+
- Skills Table (technical expertise)
|
|
186
|
+
|
|
187
|
+
**Configuration reference:**
|
|
188
|
+
- Collection options
|
|
189
|
+
- Organizer types (`simple_list`, `items_by_category`, `grouped_by`, `nested`)
|
|
190
|
+
- Supported field types
|
|
191
|
+
- Field configuration syntax
|
|
192
|
+
|
|
193
|
+
## Fallback System
|
|
194
|
+
|
|
195
|
+
When Baserow is unavailable, the plugin automatically falls back to Jekyll collections:
|
|
196
|
+
|
|
197
|
+
1. **No `BASEROW_TOKEN`**: Uses all Jekyll collections
|
|
198
|
+
2. **Missing table ID**: Uses fallback for that collection
|
|
199
|
+
3. **API Error**: Falls back gracefully with error logging
|
|
200
|
+
|
|
201
|
+
Create fallback collections in `_collections/`:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
_collections/
|
|
205
|
+
├── _experiences/
|
|
206
|
+
│ ├── experience-1.md
|
|
207
|
+
│ └── experience-2.md
|
|
208
|
+
└── _blog_posts/
|
|
209
|
+
└── my-post.md
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Automation & Deployment
|
|
213
|
+
|
|
214
|
+
### GitHub Actions Workflow
|
|
215
|
+
|
|
216
|
+
Copy the workflow template to your repository:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
cp docs/templates/github-actions_baserow-sync.yml .github/workflows/baserow-sync.yml
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Full workflow file:** [`docs/templates/github-actions_baserow-sync.yml`](docs/templates/github-actions_baserow-sync.yml)
|
|
223
|
+
|
|
224
|
+
### Automatic Sync with Baserow Webhooks
|
|
225
|
+
|
|
226
|
+
Unlike Notion, Baserow tables support **native webhooks** with custom HTTP headers, so they
|
|
227
|
+
can call the GitHub REST API directly — no relay or serverless function needed:
|
|
228
|
+
|
|
229
|
+
1. **Create a GitHub Personal Access Token** (fine-grained, scoped to this repo) with the
|
|
230
|
+
**Actions: Read and write** permission. This is what lets Baserow trigger the workflow.
|
|
231
|
+
2. In Baserow, open your table → **Webhooks** → **Create webhook**:
|
|
232
|
+
- **Events**: `Rows created`, `Rows updated`, `Rows deleted` (pick what you need)
|
|
233
|
+
- **URL**: `https://api.github.com/repos/<owner>/<repo>/actions/workflows/baserow-sync.yml/dispatches`
|
|
234
|
+
- **Method**: `POST`
|
|
235
|
+
- **Headers**:
|
|
236
|
+
- `Authorization: Bearer <your PAT>`
|
|
237
|
+
- `Accept: application/vnd.github+json`
|
|
238
|
+
- **Body** (JSON): `{"ref": "main"}`
|
|
239
|
+
|
|
240
|
+
The `baserow_event`/`table_id` inputs in the template have defaults, so a minimal
|
|
241
|
+
`{"ref": "main"}` body is enough — those inputs mainly help distinguish manual/CLI runs.
|
|
242
|
+
3. Repeat per table you want to watch (Baserow webhooks are scoped to one table).
|
|
243
|
+
|
|
244
|
+
Or trigger the workflow manually via GitHub CLI:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
gh workflow run baserow-sync.yml \
|
|
248
|
+
-f baserow_event=manual \
|
|
249
|
+
-f table_id=all
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Or via the GitHub Actions UI by clicking "Run workflow" on the Actions tab.
|
|
253
|
+
|
|
254
|
+
## Development
|
|
255
|
+
|
|
256
|
+
After checking out the repo:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# Install dependencies
|
|
260
|
+
bundle install
|
|
261
|
+
|
|
262
|
+
# Run tests
|
|
263
|
+
bundle exec rspec
|
|
264
|
+
|
|
265
|
+
# Run linter
|
|
266
|
+
bundle exec rubocop
|
|
267
|
+
|
|
268
|
+
# Run console
|
|
269
|
+
bundle exec rake console
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Contributing
|
|
273
|
+
|
|
274
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/maxime-lenne/jekyll-baserow-headless-cms.
|
|
275
|
+
|
|
276
|
+
1. Fork it
|
|
277
|
+
2. Create your feature branch (`git checkout -b feature/my-feature`)
|
|
278
|
+
3. Commit your changes (`git commit -am 'Add my feature'`)
|
|
279
|
+
4. Push to the branch (`git push origin feature/my-feature`)
|
|
280
|
+
5. Create a Pull Request
|
|
281
|
+
|
|
282
|
+
## License
|
|
283
|
+
|
|
284
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
285
|
+
|
|
286
|
+
## Author
|
|
287
|
+
|
|
288
|
+
**Maxime Lenne** - [maxime-lenne.fr](https://maxime-lenne.fr)
|
|
289
|
+
|
|
290
|
+
- GitHub: [@maxime-lenne](https://github.com/maxime-lenne)
|
|
291
|
+
- LinkedIn: [maximelenne](https://linkedin.com/in/maximelenne)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
require 'rubocop/rake_task'
|
|
6
|
+
|
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
8
|
+
RuboCop::RakeTask.new
|
|
9
|
+
|
|
10
|
+
task default: %i[spec rubocop]
|
|
11
|
+
|
|
12
|
+
desc 'Run all tests and linters'
|
|
13
|
+
task ci: %i[spec rubocop]
|
|
14
|
+
|
|
15
|
+
desc 'Build and install gem locally'
|
|
16
|
+
task :install_local do
|
|
17
|
+
sh 'gem build jekyll-baserow-headless-cms.gemspec'
|
|
18
|
+
sh 'gem install jekyll-baserow-headless-cms-*.gem'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc 'Run console with gem loaded'
|
|
22
|
+
task :console do
|
|
23
|
+
require 'pry'
|
|
24
|
+
require_relative 'lib/jekyll-baserow-headless-cms'
|
|
25
|
+
Pry.start
|
|
26
|
+
end
|