spina-blocks 0.2.0 → 0.3.1

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -12
  3. data/Rakefile +20 -2
  4. data/app/assets/javascripts/spina/controllers/block_collection_controller.js +188 -44
  5. data/app/controllers/spina/blocks/admin/blocks_controller.rb +64 -20
  6. data/app/controllers/spina/blocks/admin/categories_controller.rb +6 -6
  7. data/app/controllers/spina/blocks/admin/page_blocks_controller.rb +9 -9
  8. data/app/helpers/spina/blocks/blocks_helper.rb +3 -3
  9. data/app/models/concerns/spina/parts/block_filterable.rb +18 -0
  10. data/app/models/spina/blocks/account_extension.rb +27 -0
  11. data/app/models/spina/blocks/block.rb +5 -5
  12. data/app/models/spina/blocks/category.rb +1 -1
  13. data/app/models/spina/blocks/page_block.rb +2 -2
  14. data/app/models/spina/blocks/page_extension.rb +14 -0
  15. data/app/models/spina/blocks/search_extension.rb +15 -0
  16. data/app/models/spina/parts/block_collection.rb +2 -0
  17. data/app/models/spina/parts/block_reference.rb +2 -0
  18. data/app/views/spina/admin/parts/block_collections/_form.html.erb +41 -22
  19. data/app/views/spina/admin/parts/block_references/_form.html.erb +2 -2
  20. data/app/views/spina/admin/pro/search/results/_block.html.erb +23 -0
  21. data/app/views/spina/blocks/admin/blocks/_form_block_content.html.erb +2 -2
  22. data/app/views/spina/blocks/admin/blocks/_modal_form.html.erb +61 -0
  23. data/app/views/spina/blocks/admin/blocks/_new_block_form.html.erb +1 -1
  24. data/app/views/spina/blocks/admin/blocks/_new_block_modal_form.html.erb +42 -0
  25. data/app/views/spina/blocks/admin/blocks/edit_modal.html.erb +3 -0
  26. data/app/views/spina/blocks/admin/blocks/index.html.erb +1 -1
  27. data/app/views/spina/blocks/admin/blocks/new.html.erb +5 -1
  28. data/app/views/spina/blocks/admin/page_blocks/index.html.erb +3 -3
  29. data/config/locales/en.yml +1 -0
  30. data/config/routes.rb +5 -3
  31. data/db/migrate/1_create_spina_blocks_categories.rb +36 -0
  32. data/db/migrate/2_create_spina_blocks_blocks.rb +39 -0
  33. data/db/migrate/3_create_spina_blocks_page_blocks.rb +36 -0
  34. data/db/migrate/5_rename_title_to_name_in_spina_blocks_blocks.rb +18 -0
  35. data/lib/generators/spina/blocks/install_generator.rb +17 -0
  36. data/lib/spina/blocks/engine.rb +25 -25
  37. data/lib/spina/blocks/version.rb +1 -1
  38. data/lib/spina-blocks.rb +3 -3
  39. metadata +73 -13
  40. data/app/overrides/spina/account_override.rb +0 -19
  41. data/app/overrides/spina/page_override.rb +0 -6
  42. data/db/migrate/20250101000001_create_spina_blocks_categories.rb +0 -31
  43. data/db/migrate/20250101000002_create_spina_blocks_blocks.rb +0 -35
  44. data/db/migrate/20250101000003_create_spina_blocks_page_blocks.rb +0 -31
  45. data/db/migrate/20250101000004_remove_name_from_spina_blocks_blocks.rb +0 -24
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RenameTitleToNameInSpinaBlocksBlocks < ActiveRecord::Migration[7.0]
4
+ def change
5
+ # For fresh installs: migration 2 already creates only `name`, no `title`.
6
+ return unless connection.column_exists?(:spina_blocks_blocks, :title)
7
+
8
+ # Edge case: both `title` and `name` exist (migration 2 ran with both
9
+ # columns but migration 4, which removed `name`, was never executed).
10
+ if connection.column_exists?(:spina_blocks_blocks, :name)
11
+ remove_index(:spina_blocks_blocks, :name) if connection.index_exists?(:spina_blocks_blocks, :name)
12
+ remove_column(:spina_blocks_blocks, :name, :string)
13
+ end
14
+
15
+ rename_column(:spina_blocks_blocks, :title, :name)
16
+ add_index(:spina_blocks_blocks, :name, unique: true)
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Blocks
5
+ class InstallGenerator < Rails::Generators::Base
6
+ desc "Install Spina Blocks plugin: copy migrations and run them"
7
+
8
+ def copy_migrations
9
+ rake("spina_blocks:install:migrations")
10
+ end
11
+
12
+ def run_migrations
13
+ rake("db:migrate")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -7,8 +7,8 @@ module Spina
7
7
 
8
8
  config.before_initialize do
9
9
  ::Spina::Plugin.register do |plugin|
10
- plugin.name = 'blocks'
11
- plugin.namespace = 'blocks'
10
+ plugin.name = "blocks"
11
+ plugin.namespace = "blocks"
12
12
  end
13
13
 
14
14
  ::Spina::Theme.class_eval do
@@ -26,55 +26,55 @@ module Spina
26
26
  end
27
27
  end
28
28
 
29
- initializer 'spina.blocks.append_migrations' do |app|
30
- unless app.root.to_s.match?(root.to_s)
31
- config.paths['db/migrate'].expanded.each do |expanded_path|
32
- app.config.paths['db/migrate'] << expanded_path
33
- end
34
- end
35
- end
36
-
37
- initializer 'spina.blocks.importmap', before: 'spina.blocks.register_parts' do
29
+ initializer "spina.blocks.importmap", before: "spina.blocks.register_parts" do
38
30
  Spina.config.importmap.draw do
39
- pin_all_from Spina::Blocks::Engine.root.join('app/assets/javascripts/spina/controllers'),
40
- under: 'controllers', to: 'spina/controllers'
31
+ pin_all_from Spina::Blocks::Engine.root.join("app/assets/javascripts/spina/controllers"),
32
+ under: "controllers",
33
+ to: "spina/controllers"
41
34
  end
42
35
  end
43
36
 
44
- initializer 'spina.blocks.assets.precompile' do |app|
45
- app.config.assets.precompile += %w[spina/controllers/block_collection_controller.js] if defined?(Sprockets)
37
+ initializer "spina.blocks.assets.precompile" do |app|
38
+ app.config.assets.precompile += ["spina/controllers/block_collection_controller.js"] if defined?(Sprockets)
46
39
  end
47
40
 
48
- initializer 'spina.blocks.register_parts' do
41
+ initializer "spina.blocks.register_parts" do
49
42
  config.to_prepare do
50
43
  ::Spina::Part.register(
51
44
  Spina::Parts::BlockReference,
52
- Spina::Parts::BlockCollection
45
+ Spina::Parts::BlockCollection,
53
46
  )
54
47
  end
55
48
  end
56
49
 
57
- initializer 'spina.blocks.extend_page' do
50
+ initializer "spina.blocks.extend_models" do
51
+ config.to_prepare do
52
+ Spina::Page.include(Spina::Blocks::PageExtension) unless Spina::Page < Spina::Blocks::PageExtension
53
+ Spina::Account.include(Spina::Blocks::AccountExtension) unless Spina::Account < Spina::Blocks::AccountExtension
54
+ end
55
+ end
56
+
57
+ initializer "spina.blocks.search" do
58
58
  config.to_prepare do
59
- Dir.glob(Spina::Blocks::Engine.root.join('app/overrides/**/*.rb')).sort.each do |override|
60
- load override
59
+ if defined?(Spina::Pro::Search)
60
+ Spina::Blocks::Block.include(Spina::Blocks::SearchExtension) unless Spina::Blocks::Block < Spina::Blocks::SearchExtension
61
61
  end
62
62
  end
63
63
  end
64
64
 
65
- initializer 'spina.blocks.tailwind_content' do
65
+ initializer "spina.blocks.tailwind_content" do
66
66
  ::Spina.config.tailwind_content << "#{Spina::Blocks::Engine.root}/app/views/**/*.*"
67
67
  ::Spina.config.tailwind_content << "#{Spina::Blocks::Engine.root}/app/helpers/**/*.*"
68
68
  ::Spina.config.tailwind_content << "#{Spina::Blocks::Engine.root}/app/assets/javascripts/**/*.js"
69
69
  end
70
70
 
71
- initializer 'spina.blocks.i18n' do
72
- config.i18n.load_path += Dir[Spina::Blocks::Engine.root.join('config', 'locales', '*.{rb,yml}')]
71
+ initializer "spina.blocks.i18n" do
72
+ config.i18n.load_path += Dir[Spina::Blocks::Engine.root.join("config", "locales", "*.{rb,yml}")]
73
73
  end
74
74
 
75
- initializer 'spina.blocks.helpers' do
75
+ initializer "spina.blocks.helpers" do
76
76
  config.to_prepare do
77
- ActionView::Base.include Spina::Blocks::BlocksHelper
77
+ ActionView::Base.include(Spina::Blocks::BlocksHelper)
78
78
  end
79
79
  end
80
80
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Spina
4
4
  module Blocks
5
- VERSION = '0.2.0'
5
+ VERSION = "0.3.1"
6
6
  end
7
7
  end
data/lib/spina-blocks.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spina'
4
- require 'spina/blocks/version'
5
- require 'spina/blocks/engine'
3
+ require "spina"
4
+ require "spina/blocks/version"
5
+ require "spina/blocks/engine"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spina-blocks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Kanashchuk
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-03-11 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: spina
@@ -24,6 +23,62 @@ dependencies:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
25
  version: '2.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: database_cleaner-active_record
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: factory_bot_rails
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: pg
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec-rails
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
27
82
  description: A plugin for Spina CMS that adds reusable block components that can be
28
83
  assembled into pages.
29
84
  email:
@@ -39,34 +94,41 @@ files:
39
94
  - app/controllers/spina/blocks/admin/categories_controller.rb
40
95
  - app/controllers/spina/blocks/admin/page_blocks_controller.rb
41
96
  - app/helpers/spina/blocks/blocks_helper.rb
97
+ - app/models/concerns/spina/parts/block_filterable.rb
98
+ - app/models/spina/blocks/account_extension.rb
42
99
  - app/models/spina/blocks/application_record.rb
43
100
  - app/models/spina/blocks/block.rb
44
101
  - app/models/spina/blocks/category.rb
45
102
  - app/models/spina/blocks/page_block.rb
103
+ - app/models/spina/blocks/page_extension.rb
104
+ - app/models/spina/blocks/search_extension.rb
46
105
  - app/models/spina/parts/block_collection.rb
47
106
  - app/models/spina/parts/block_reference.rb
48
- - app/overrides/spina/account_override.rb
49
- - app/overrides/spina/page_override.rb
50
107
  - app/views/spina/admin/hooks/blocks/_website_secondary_navigation.html.erb
51
108
  - app/views/spina/admin/parts/block_collections/_form.html.erb
52
109
  - app/views/spina/admin/parts/block_references/_form.html.erb
110
+ - app/views/spina/admin/pro/search/results/_block.html.erb
53
111
  - app/views/spina/blocks/admin/blocks/_button_block_content.html.erb
54
112
  - app/views/spina/blocks/admin/blocks/_button_block_settings.html.erb
55
113
  - app/views/spina/blocks/admin/blocks/_form.html.erb
56
114
  - app/views/spina/blocks/admin/blocks/_form_block_content.html.erb
57
115
  - app/views/spina/blocks/admin/blocks/_form_block_settings.html.erb
116
+ - app/views/spina/blocks/admin/blocks/_modal_form.html.erb
58
117
  - app/views/spina/blocks/admin/blocks/_new_block_form.html.erb
118
+ - app/views/spina/blocks/admin/blocks/_new_block_modal_form.html.erb
59
119
  - app/views/spina/blocks/admin/blocks/edit.html.erb
60
120
  - app/views/spina/blocks/admin/blocks/edit_content.html.erb
121
+ - app/views/spina/blocks/admin/blocks/edit_modal.html.erb
61
122
  - app/views/spina/blocks/admin/blocks/index.html.erb
62
123
  - app/views/spina/blocks/admin/blocks/new.html.erb
63
124
  - app/views/spina/blocks/admin/page_blocks/index.html.erb
64
125
  - config/locales/en.yml
65
126
  - config/routes.rb
66
- - db/migrate/20250101000001_create_spina_blocks_categories.rb
67
- - db/migrate/20250101000002_create_spina_blocks_blocks.rb
68
- - db/migrate/20250101000003_create_spina_blocks_page_blocks.rb
69
- - db/migrate/20250101000004_remove_name_from_spina_blocks_blocks.rb
127
+ - db/migrate/1_create_spina_blocks_categories.rb
128
+ - db/migrate/2_create_spina_blocks_blocks.rb
129
+ - db/migrate/3_create_spina_blocks_page_blocks.rb
130
+ - db/migrate/5_rename_title_to_name_in_spina_blocks_blocks.rb
131
+ - lib/generators/spina/blocks/install_generator.rb
70
132
  - lib/spina-blocks.rb
71
133
  - lib/spina/blocks/engine.rb
72
134
  - lib/spina/blocks/version.rb
@@ -75,7 +137,6 @@ licenses:
75
137
  - MIT
76
138
  metadata:
77
139
  rubygems_mfa_required: 'true'
78
- post_install_message:
79
140
  rdoc_options: []
80
141
  require_paths:
81
142
  - lib
@@ -83,15 +144,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
83
144
  requirements:
84
145
  - - ">="
85
146
  - !ruby/object:Gem::Version
86
- version: 2.7.0
147
+ version: 3.2.0
87
148
  required_rubygems_version: !ruby/object:Gem::Requirement
88
149
  requirements:
89
150
  - - ">="
90
151
  - !ruby/object:Gem::Version
91
152
  version: '0'
92
153
  requirements: []
93
- rubygems_version: 3.5.22
94
- signing_key:
154
+ rubygems_version: 3.6.9
95
155
  specification_version: 4
96
156
  summary: Block component library for Spina CMS
97
157
  test_files: []
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Spina::Account.class_eval do
4
- after_save :bootstrap_block_categories
5
-
6
- private
7
-
8
- def bootstrap_block_categories
9
- theme_config = Spina::Theme.find_by_name(theme)
10
- return unless theme_config
11
- return unless theme_config.respond_to?(:block_categories) && theme_config.block_categories.present?
12
-
13
- theme_config.block_categories.each_with_index do |category, index|
14
- Spina::Blocks::Category.where(name: category[:name])
15
- .first_or_create(label: category[:label])
16
- .update(label: category[:label], position: index)
17
- end
18
- end
19
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Spina::Page.class_eval do
4
- has_many :page_blocks, class_name: 'Spina::Blocks::PageBlock', foreign_key: :page_id, dependent: :destroy
5
- has_many :blocks, through: :page_blocks, class_name: 'Spina::Blocks::Block'
6
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CreateSpinaBlocksCategories < ActiveRecord::Migration[7.0]
4
- def change
5
- if legacy_migration_applied?
6
- cleanup_legacy_version!
7
- return
8
- end
9
-
10
- create_table :spina_blocks_categories do |t|
11
- t.string :name, null: false
12
- t.string :label, null: false
13
- t.integer :position, default: 0
14
-
15
- t.timestamps
16
- end
17
-
18
- add_index :spina_blocks_categories, :name, unique: true
19
- end
20
-
21
- private
22
-
23
- def legacy_migration_applied?
24
- ActiveRecord::Base.connection
25
- .select_value("SELECT 1 FROM schema_migrations WHERE version = '1'")
26
- end
27
-
28
- def cleanup_legacy_version!
29
- execute "DELETE FROM schema_migrations WHERE version = '1'"
30
- end
31
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CreateSpinaBlocksBlocks < ActiveRecord::Migration[7.0]
4
- def change
5
- if legacy_migration_applied?
6
- cleanup_legacy_version!
7
- return
8
- end
9
-
10
- create_table :spina_blocks_blocks do |t|
11
- t.string :title, null: false
12
- t.string :name, null: false
13
- t.string :block_template, null: false
14
- t.references :category, foreign_key: { to_table: :spina_blocks_categories }, null: true
15
- t.integer :position, default: 0
16
- t.boolean :active, default: true
17
- t.json :json_attributes
18
-
19
- t.timestamps
20
- end
21
-
22
- add_index :spina_blocks_blocks, :name, unique: true
23
- end
24
-
25
- private
26
-
27
- def legacy_migration_applied?
28
- ActiveRecord::Base.connection
29
- .select_value("SELECT 1 FROM schema_migrations WHERE version = '2'")
30
- end
31
-
32
- def cleanup_legacy_version!
33
- execute "DELETE FROM schema_migrations WHERE version = '2'"
34
- end
35
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CreateSpinaBlocksPageBlocks < ActiveRecord::Migration[7.0]
4
- def change
5
- if legacy_migration_applied?
6
- cleanup_legacy_version!
7
- return
8
- end
9
-
10
- create_table :spina_blocks_page_blocks do |t|
11
- t.references :page, null: false, foreign_key: { to_table: :spina_pages }
12
- t.references :block, null: false, foreign_key: { to_table: :spina_blocks_blocks }
13
- t.integer :position, default: 0
14
-
15
- t.timestamps
16
- end
17
-
18
- add_index :spina_blocks_page_blocks, %i[page_id block_id], unique: true
19
- end
20
-
21
- private
22
-
23
- def legacy_migration_applied?
24
- ActiveRecord::Base.connection
25
- .select_value("SELECT 1 FROM schema_migrations WHERE version = '3'")
26
- end
27
-
28
- def cleanup_legacy_version!
29
- execute "DELETE FROM schema_migrations WHERE version = '3'"
30
- end
31
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class RemoveNameFromSpinaBlocksBlocks < ActiveRecord::Migration[7.0]
4
- def change
5
- if legacy_migration_applied?
6
- cleanup_legacy_version!
7
- return
8
- end
9
-
10
- remove_index :spina_blocks_blocks, :name
11
- remove_column :spina_blocks_blocks, :name, :string
12
- end
13
-
14
- private
15
-
16
- def legacy_migration_applied?
17
- ActiveRecord::Base.connection
18
- .select_value("SELECT 1 FROM schema_migrations WHERE version = '4'")
19
- end
20
-
21
- def cleanup_legacy_version!
22
- execute "DELETE FROM schema_migrations WHERE version = '4'"
23
- end
24
- end