Module: JekyllBaserowHeadlessCMS::DataOrganizers

Defined in:
lib/jekyll_baserow_headless_cms/data_organizers.rb

Overview

Module for organizing Baserow data into different structures

Class Method Summary collapse

Class Method Details

.build_category_hash(category_data) ⇒ Object

Build the category hash structure



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 92

def build_category_hash(category_data)
  order = category_data[:order]
  {
    'title' => category_data[:name],
    'category' => category_data[:name],
    'subcategory' => nil,
    'icon' => category_data[:icon],
    'order' => (order.is_a?(Array) ? order.first : order) || 999,
    'items' => []
  }
end

.build_category_item(row, name, category_data) ⇒ Object

Build an item hash for category organization



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 105

def build_category_item(row, name, category_data)
  {
    'name' => name,
    'level' => FieldExtractors.extract(row, 'Level', 'number'),
    'years' => FieldExtractors.extract(row, 'Years', 'number'),
    'description' => nil,
    'icon' => nil,
    'color' => category_data[:color],
    'featured' => FieldExtractors.extract(row, 'Featured', 'boolean'),
    'order' => FieldExtractors.extract(row, 'Order', 'number') || 999,
    'id' => row['id']
  }
end

.data_present?(data) ⇒ Boolean

Check if data is present (non-empty)

Parameters:

  • data (Hash, Array)

    Data to check

Returns:

  • (Boolean)

    True if data is present



239
240
241
242
243
244
245
246
247
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 239

def data_present?(data)
  return false if data.nil?

  if data.is_a?(Hash)
    data.size.positive?
  else
    data.length.positive?
  end
end

.extract_category_data(row) ⇒ Object

Extract category-related data from a row (via lookup fields, Baserow's rollup equivalent)



82
83
84
85
86
87
88
89
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 82

def extract_category_data(row)
  {
    name: FieldExtractors.extract(row, 'Category', 'lookup') || 'Other',
    icon: FieldExtractors.extract(row, 'Icon', 'lookup'),
    color: FieldExtractors.extract(row, 'Color', 'lookup'),
    order: FieldExtractors.extract(row, 'Category Order', 'lookup')
  }
end

.organize(baserow_data, config) ⇒ Hash, Array

Organize data based on the specified organizer type

Parameters:

  • baserow_data (Hash)

    Raw data from the Baserow API (rows under 'results')

  • config (Hash)

    Collection configuration

Returns:

  • (Hash, Array)

    Organized data



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 12

def organize(baserow_data, config)
  organizer = config['organizer'] || 'simple_list'
  fields_config = config['fields'] || []
  sort_by = config['sort_by']
  sort_order = config['sort_order'] || 'asc'

  case organizer
  when 'simple_list'
    organize_simple_list(baserow_data, fields_config, sort_by, sort_order)
  when 'items_by_category'
    organize_items_by_category(baserow_data, fields_config)
  when 'grouped_by'
    group_field = config['group_by']
    organize_grouped_by(baserow_data, fields_config, group_field, sort_by, sort_order)
  when 'nested'
    parent_field = config['parent_field'] || 'parent_id'
    organize_nested(baserow_data, fields_config, parent_field, sort_by, sort_order)
  else
    organize_simple_list(baserow_data, fields_config, sort_by, sort_order)
  end
end

.organize_grouped_by(baserow_data, fields_config, group_field, sort_by, sort_order) ⇒ Hash

Organize items grouped by a field

Parameters:

  • baserow_data (Hash)

    Raw data from the Baserow API

  • fields_config (Array<Hash>)

    Field configuration

  • group_field (String)

    Field to group by

  • sort_by (String)

    Field to sort by within groups

  • sort_order (String)

    Sort order

Returns:

  • (Hash)

    Items grouped by field



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 140

def organize_grouped_by(baserow_data, fields_config, group_field, sort_by, sort_order)
  grouped = {}

  baserow_data['results'].each do |row|
    item = FieldExtractors.extract_all(row, fields_config)
    item['id'] = row['id']

    next if item['title'].nil? || item['title'].to_s.empty?

    group_key = item[group_field]
    group_key = group_key.first if group_key.is_a?(Array)
    group_key ||= 'Other'

    grouped[group_key] ||= []
    grouped[group_key] << item
  end

  # Sort within groups
  grouped.each_value do |items|
    sort_items(items, sort_by, sort_order)
  end

  grouped
end

.organize_items_by_category(baserow_data, _fields_config) ⇒ Hash

Organize items grouped by category Useful for skills, products, team members, or any items with category grouping

Parameters:

  • baserow_data (Hash)

    Raw data from the Baserow API

  • fields_config (Array<Hash>)

    Field configuration

Returns:

  • (Hash)

    Items grouped by category



59
60
61
62
63
64
65
66
67
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 59

def organize_items_by_category(baserow_data, _fields_config)
  items_by_category = {}

  baserow_data['results'].each do |row|
    process_category_row(row, items_by_category)
  end

  sort_categories_and_items(items_by_category)
end

.organize_nested(baserow_data, fields_config, parent_field, sort_by, sort_order) ⇒ Array<Hash>

Organize items in a nested tree structure

Parameters:

  • baserow_data (Hash)

    Raw data from the Baserow API

  • fields_config (Array<Hash>)

    Field configuration

  • parent_field (String)

    Field containing parent reference

  • sort_by (String)

    Field to sort by

  • sort_order (String)

    Sort order

Returns:

  • (Array<Hash>)

    Nested tree of items



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 172

def organize_nested(baserow_data, fields_config, parent_field, sort_by, sort_order)
  items = {}
  roots = []

  # First pass: extract all items
  baserow_data['results'].each do |row|
    item = FieldExtractors.extract_all(row, fields_config)
    item['id'] = row['id']
    item['children'] = []
    items[row['id']] = item
  end

  # Second pass: build tree structure
  items.each_value do |item|
    parent_ids = item[parent_field]
    parent_id = parent_ids.is_a?(Array) ? parent_ids.first : parent_ids

    if parent_id && items[parent_id]
      items[parent_id]['children'] << item
    else
      roots << item
    end
  end

  # Sort at each level
  sort_nested(roots, sort_by, sort_order)

  roots
end

.organize_simple_list(baserow_data, fields_config, sort_by, sort_order) ⇒ Array<Hash>

Organize as a simple sorted list

Parameters:

  • baserow_data (Hash)

    Raw data from the Baserow API

  • fields_config (Array<Hash>)

    Field configuration

  • sort_by (String)

    Field to sort by

  • sort_order (String)

    Sort order ('asc' or 'desc')

Returns:

  • (Array<Hash>)

    Sorted list of items



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 40

def organize_simple_list(baserow_data, fields_config, sort_by, sort_order)
  items = baserow_data['results'].map do |row|
    item = FieldExtractors.extract_all(row, fields_config)
    item['id'] = row['id']
    item
  end

  # Filter out items without title
  items = items.select { |item| item['title'] && !item['title'].to_s.empty? }

  # Sort if sort_by is specified
  sort_items(items, sort_by, sort_order)
end

.process_category_row(row, items_by_category) ⇒ Object

Process a single row for category organization



70
71
72
73
74
75
76
77
78
79
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 70

def process_category_row(row, items_by_category)
  name = FieldExtractors.extract(row, 'Name', 'text')
  return if name.nil? || name.empty?

  category_data = extract_category_data(row)
  category_name = category_data[:name]

  items_by_category[category_name] ||= build_category_hash(category_data)
  items_by_category[category_name]['items'] << build_category_item(row, name, category_data)
end

.sort_categories_and_items(items_by_category) ⇒ Object

Sort categories and their items



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 120

def sort_categories_and_items(items_by_category)
  sorted = items_by_category.sort_by do |_, data|
    order = data['order']
    (order.is_a?(Array) ? order.first : order).to_i
  end.to_h

  sorted.each_value do |data|
    data['items'].sort_by! { |item| item['order'].to_i }
  end

  sorted
end

.sort_items(items, sort_by, sort_order) ⇒ Array<Hash>

Sort items by field

Parameters:

  • items (Array<Hash>)

    Items to sort

  • sort_by (String)

    Field to sort by

  • sort_order (String)

    Sort order ('asc' or 'desc')

Returns:

  • (Array<Hash>)

    Sorted items



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 207

def sort_items(items, sort_by, sort_order)
  return items unless sort_by && !sort_by.empty?

  items.sort_by! do |item|
    value = item[sort_by]
    case value
    when nil then sort_order == 'desc' ? -Float::INFINITY : Float::INFINITY
    when Numeric then value
    when String then value.downcase
    else value.to_s.downcase
    end
  end

  items.reverse! if sort_order == 'desc'
  items
end

.sort_nested(items, sort_by, sort_order) ⇒ Object

Recursively sort nested items

Parameters:

  • items (Array<Hash>)

    Items to sort

  • sort_by (String)

    Field to sort by

  • sort_order (String)

    Sort order



228
229
230
231
232
233
234
# File 'lib/jekyll_baserow_headless_cms/data_organizers.rb', line 228

def sort_nested(items, sort_by, sort_order)
  sort_items(items, sort_by, sort_order)

  items.each do |item|
    sort_nested(item['children'], sort_by, sort_order) if item['children']&.any?
  end
end