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 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
@@ -0,0 +1,12 @@
1
+ {
2
+ "enabledMcpjsonServers": ["github", "context7", "chrome-devtools"],
3
+ "disabledMcpjsonServers": [
4
+ "figma-desktop",
5
+ "sentry",
6
+ "n8n-mcp-staging",
7
+ "n8n-mcp-prod",
8
+ "MCP_DOCKER",
9
+ "excalidraw-staging",
10
+ "pencil"
11
+ ]
12
+ }
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
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
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
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in jekyll-baserow-headless-cms.gemspec
6
+ gemspec
7
+
8
+ group :development do
9
+ gem 'pry', '~> 0.14'
10
+ end
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