alchemy_cms 6.0.0.b2 → 6.0.0.pre.b6
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 +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +14 -2
- data/Rakefile +37 -23
- data/app/assets/stylesheets/alchemy/_extends.scss +15 -2
- data/app/assets/stylesheets/alchemy/archive.scss +2 -1
- data/app/assets/stylesheets/alchemy/fonts.scss +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.svg +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.ttf +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.woff +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.svg +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.ttf +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.woff +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/img/anchor.gif +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/img/loader.gif +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/img/object.gif +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/img/trans.gif +0 -0
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +0 -0
- data/app/controllers/alchemy/admin/elements_controller.rb +9 -4
- data/app/decorators/alchemy/element_editor.rb +7 -4
- data/app/decorators/alchemy/ingredient_editor.rb +5 -1
- data/app/helpers/alchemy/elements_block_helper.rb +14 -6
- data/app/models/alchemy/element/element_essences.rb +14 -3
- data/app/models/alchemy/element/element_ingredients.rb +11 -3
- data/app/models/alchemy/element/presenters.rb +9 -2
- data/app/models/alchemy/element.rb +0 -14
- data/app/models/alchemy/ingredient.rb +16 -62
- data/app/models/alchemy/page/page_natures.rb +1 -10
- data/app/models/alchemy/page.rb +3 -3
- data/app/models/alchemy/page_version.rb +1 -1
- data/app/views/alchemy/admin/elements/create.js.erb +1 -1
- data/app/views/alchemy/admin/elements/destroy.js.erb +1 -3
- data/app/views/alchemy/admin/elements/fold.js.erb +2 -2
- data/app/views/alchemy/admin/elements/update.js.erb +1 -1
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_file_editor.html.erb +3 -1
- data/app/views/alchemy/ingredients/_headline_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_html_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_link_editor.html.erb +8 -8
- data/app/views/alchemy/ingredients/_node_editor.html.erb +1 -0
- data/app/views/alchemy/ingredients/_page_editor.html.erb +1 -0
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +7 -6
- data/app/views/alchemy/ingredients/_select_editor.html.erb +1 -0
- data/app/views/alchemy/ingredients/_text_editor.html.erb +5 -4
- data/lib/alchemy/test_support/shared_ingredient_examples.rb +0 -1
- data/lib/alchemy/tinymce.rb +4 -0
- data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +4 -1
- data/lib/alchemy/version.rb +1 -1
- data/package.json +1 -1
- metadata +4 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a2356162437442579cc431fade3fc3486f5262d22e6a6212950634e5ac90f595
|
|
4
|
+
data.tar.gz: 4a933ae8c9652adbe6fef16cf2e420c31160b4352fb2fba3a15f536f67f1dbc0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 807c2793f1805245bf12512582f2bfd06acdc777a811b070877447792d20b5cfae46b7e04276d90aed455f97fca91f88385df51317a294b9569b7e845017dfbe
|
|
7
|
+
data.tar.gz: 04ec712fe19f499cf0174ee0d044a6c086abec3c063cfa5df32380033de40f4373c9e0978f626a74ac83a67b190ef4154566da152b39e02dba47b15bc6d9e94f
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
## 6.0.0-b6 (2021-09-02)
|
|
2
|
+
|
|
3
|
+
- Fix element with ingredients preview text [#2187](https://github.com/AlchemyCMS/alchemy_cms/pull/2187) ([tvdeyen](https://github.com/tvdeyen))
|
|
4
|
+
- Do not validate element during toggle fold and create [#2186](https://github.com/AlchemyCMS/alchemy_cms/pull/2186) ([tvdeyen](https://github.com/tvdeyen))
|
|
5
|
+
## 6.0.0-b5 (2021-08-27)
|
|
6
|
+
|
|
7
|
+
- Remove spec that tests default data store value [#2184](https://github.com/AlchemyCMS/alchemy_cms/pull/2184) ([tvdeyen](https://github.com/tvdeyen))
|
|
8
|
+
- Remove data store accessor from ingredient base class [#2183](https://github.com/AlchemyCMS/alchemy_cms/pull/2183) ([tvdeyen](https://github.com/tvdeyen))
|
|
9
|
+
|
|
10
|
+
## 6.0.0-b4 (2021-08-27)
|
|
11
|
+
|
|
12
|
+
- Load custom Tinymce config for ingredients [#2182](https://github.com/AlchemyCMS/alchemy_cms/pull/2182) ([tvdeyen](https://github.com/tvdeyen))
|
|
13
|
+
- Fix ingredient editor selector in element update callback [#2181](https://github.com/AlchemyCMS/alchemy_cms/pull/2181) ([tvdeyen](https://github.com/tvdeyen))
|
|
14
|
+
- Ingredient by role block level helper [#2180](https://github.com/AlchemyCMS/alchemy_cms/pull/2180) ([tvdeyen](https://github.com/tvdeyen))
|
|
15
|
+
- Fixes caching [#2179](https://github.com/AlchemyCMS/alchemy_cms/pull/2179) ([tvdeyen](https://github.com/tvdeyen))
|
|
16
|
+
- make images non-executable [#2176](https://github.com/AlchemyCMS/alchemy_cms/pull/2176) ([mensfeld](https://github.com/mensfeld))
|
|
17
|
+
- Release task [#2173](https://github.com/AlchemyCMS/alchemy_cms/pull/2173) ([tvdeyen](https://github.com/tvdeyen))
|
|
18
|
+
|
|
19
|
+
## 6.0.0.b3 (2021-08-12)
|
|
20
|
+
|
|
21
|
+
### Fixes
|
|
22
|
+
|
|
23
|
+
- Simplify ingredient creation [#2171](https://github.com/AlchemyCMS/alchemy_cms/pull/2171) ([tvdeyen](https://github.com/tvdeyen))
|
|
24
|
+
- Return ingredients value if element asked for ingredient [#2170](https://github.com/AlchemyCMS/alchemy_cms/pull/2170) ([tvdeyen](https://github.com/tvdeyen))
|
|
25
|
+
- Fix ingredient form field DOM ids [#2167](https://github.com/AlchemyCMS/alchemy_cms/pull/2167) ([tvdeyen](https://github.com/tvdeyen))
|
|
26
|
+
- Ensure resource table ends before the filter/tag sidebar [#2166](https://github.com/AlchemyCMS/alchemy_cms/pull/2166) ([robinboening](https://github.com/robinboening))
|
|
27
|
+
- Return fully namespaced ingredient constant [#2164](https://github.com/AlchemyCMS/alchemy_cms/pull/2164) ([tvdeyen](https://github.com/tvdeyen))
|
|
28
|
+
- (Re)-init Tinymce for elements with ingredients [#2163](https://github.com/AlchemyCMS/alchemy_cms/pull/2163) ([tvdeyen](https://github.com/tvdeyen))
|
|
29
|
+
|
|
1
30
|
## 6.0.0.b2 (2021-08-05)
|
|
2
31
|
|
|
3
32
|
### Features
|
data/README.md
CHANGED
|
@@ -339,6 +339,10 @@ $ bin/rails s
|
|
|
339
339
|
|
|
340
340
|
## 📦 Releasing
|
|
341
341
|
|
|
342
|
+
### Bump version
|
|
343
|
+
|
|
344
|
+
Bump the version number in both `lib/alchemy/version.rb` and `./package.json`. Make sure both are exactly the same and follow [SemVer format](https://semver.org/#semantic-versioning-specification-semver).
|
|
345
|
+
|
|
342
346
|
### Update the changelog
|
|
343
347
|
|
|
344
348
|
```bash
|
|
@@ -346,12 +350,20 @@ $ export GITHUB_ACCESS_TOKEN=...
|
|
|
346
350
|
$ PREVIOUS_VERSION=4.1.0 bundle exec rake alchemy:changelog:update
|
|
347
351
|
```
|
|
348
352
|
|
|
349
|
-
###
|
|
353
|
+
### Commit version bump
|
|
350
354
|
|
|
351
355
|
```bash
|
|
352
|
-
$
|
|
356
|
+
$ git commit -am "Bump version to vX.Y.Z"
|
|
353
357
|
```
|
|
354
358
|
|
|
359
|
+
### Release a new version
|
|
360
|
+
|
|
361
|
+
This task will publish both the ruby gem and the npm package.
|
|
362
|
+
It also tags the latest commit.
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
$ bundle exec rake alchemy:release
|
|
366
|
+
```
|
|
355
367
|
|
|
356
368
|
## ❓Getting Help
|
|
357
369
|
|
data/Rakefile
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
begin
|
|
2
|
-
require
|
|
2
|
+
require "bundler/setup"
|
|
3
3
|
rescue LoadError
|
|
4
|
-
puts
|
|
4
|
+
puts "You must `gem install bundler` and `bundle install` to run rake tasks"
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
begin
|
|
8
|
-
require
|
|
8
|
+
require "rdoc/task"
|
|
9
9
|
rescue LoadError
|
|
10
|
-
require
|
|
11
|
-
require
|
|
10
|
+
require "rdoc/rdoc"
|
|
11
|
+
require "rake/rdoctask"
|
|
12
12
|
RDoc::Task = Rake::RDocTask
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
desc
|
|
15
|
+
desc "Generate documentation for Alchemy CMS."
|
|
16
16
|
RDoc::Task.new(:rdoc) do |rdoc|
|
|
17
|
-
rdoc.rdoc_dir =
|
|
18
|
-
rdoc.title
|
|
19
|
-
rdoc.options <<
|
|
20
|
-
rdoc.rdoc_files.include(
|
|
21
|
-
rdoc.rdoc_files.include(
|
|
22
|
-
rdoc.rdoc_files.include(
|
|
23
|
-
rdoc.rdoc_files.include(
|
|
17
|
+
rdoc.rdoc_dir = "rdoc"
|
|
18
|
+
rdoc.title = "Alchemy CMS"
|
|
19
|
+
rdoc.options << "--line-numbers" << "--inline-source"
|
|
20
|
+
rdoc.rdoc_files.include("README.md")
|
|
21
|
+
rdoc.rdoc_files.include("config/alchemy/*.yml")
|
|
22
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
|
23
|
+
rdoc.rdoc_files.include("app/**/*.rb")
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
APP_RAKEFILE = File.expand_path(
|
|
27
|
-
load
|
|
26
|
+
APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
|
|
27
|
+
load "rails/tasks/engine.rake"
|
|
28
28
|
|
|
29
|
-
require
|
|
30
|
-
require
|
|
29
|
+
require "rspec/core"
|
|
30
|
+
require "rspec/core/rake_task"
|
|
31
31
|
|
|
32
32
|
RSpec::Core::RakeTask.new(:spec)
|
|
33
33
|
|
|
34
|
-
task default: [
|
|
34
|
+
task default: ["alchemy:spec:prepare", :spec]
|
|
35
35
|
|
|
36
36
|
Bundler::GemHelper.install_tasks
|
|
37
37
|
|
|
@@ -56,11 +56,11 @@ namespace :alchemy do
|
|
|
56
56
|
namespace :changelog do
|
|
57
57
|
desc "Update CHANGELOG from GitHub (Set GITHUB_ACCESS_TOKEN and PREVIOUS_VERSION to a version you want to write changelog changes for)"
|
|
58
58
|
task :update do
|
|
59
|
-
original_file =
|
|
60
|
-
new_file = original_file +
|
|
61
|
-
backup = original_file +
|
|
62
|
-
changes = `git rev-list v#{ENV[
|
|
63
|
-
File.open(new_file,
|
|
59
|
+
original_file = "./CHANGELOG.md"
|
|
60
|
+
new_file = original_file + ".new"
|
|
61
|
+
backup = original_file + ".old"
|
|
62
|
+
changes = `git rev-list v#{ENV["PREVIOUS_VERSION"]}..HEAD | bundle exec github_fast_changelog AlchemyCMS/alchemy_cms`
|
|
63
|
+
File.open(new_file, "w") do |fo|
|
|
64
64
|
fo.puts changes
|
|
65
65
|
File.foreach(original_file) do |li|
|
|
66
66
|
fo.puts li
|
|
@@ -72,4 +72,18 @@ namespace :alchemy do
|
|
|
72
72
|
File.delete(backup)
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
|
+
|
|
76
|
+
desc "Release a new Ruby gem and npm package in one command"
|
|
77
|
+
task :release do
|
|
78
|
+
require "json"
|
|
79
|
+
require_relative "lib/alchemy/version"
|
|
80
|
+
package = File.read("package.json")
|
|
81
|
+
unless JSON.parse(package)["version"] == Alchemy.version
|
|
82
|
+
abort "Ruby gem and npm package versions are out of sync! Please fix."
|
|
83
|
+
end
|
|
84
|
+
# Release the Ruby gem with bundler
|
|
85
|
+
Rake::Task["release"].invoke
|
|
86
|
+
# Publish npm package via CLI
|
|
87
|
+
system "npm publish"
|
|
88
|
+
end
|
|
75
89
|
end
|
|
@@ -31,15 +31,28 @@
|
|
|
31
31
|
line-height: $form-field-line-height;
|
|
32
32
|
transition: $transition-duration;
|
|
33
33
|
|
|
34
|
-
&:focus {
|
|
34
|
+
&:focus:not(.readonly) {
|
|
35
35
|
@include default-focus-style($box-shadow: 0 0 0 1px $focus-color);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
&[disabled],
|
|
38
|
+
&[disabled],
|
|
39
|
+
&.disabled,
|
|
40
|
+
&[readonly],
|
|
41
|
+
&.readonly {
|
|
39
42
|
color: $form-field-disabled-text-color;
|
|
40
43
|
background-color: $form-field-disabled-bg-color;
|
|
44
|
+
cursor: default;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&[disabled],
|
|
48
|
+
&.disabled {
|
|
41
49
|
cursor: not-allowed;
|
|
42
50
|
}
|
|
51
|
+
|
|
52
|
+
&[readonly],
|
|
53
|
+
&.readonly {
|
|
54
|
+
pointer-events: none;
|
|
55
|
+
}
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
%gradiated-toolbar {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -32,14 +32,14 @@ module Alchemy
|
|
|
32
32
|
if @paste_from_clipboard = params[:paste_from_clipboard].present?
|
|
33
33
|
@element = paste_element_from_clipboard
|
|
34
34
|
else
|
|
35
|
-
@element = Element.
|
|
35
|
+
@element = Element.new(create_element_params)
|
|
36
36
|
end
|
|
37
37
|
if @page.definition["insert_elements_at"] == "top"
|
|
38
38
|
@insert_at_top = true
|
|
39
|
-
@element.
|
|
39
|
+
@element.position = 1
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
|
-
if @element.
|
|
42
|
+
if @element.save
|
|
43
43
|
render :create
|
|
44
44
|
else
|
|
45
45
|
@element.page_version = @page_version
|
|
@@ -65,6 +65,7 @@ module Alchemy
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def destroy
|
|
68
|
+
@richtext_ids = @element.richtext_contents_ids + @element.richtext_ingredients_ids
|
|
68
69
|
@element.destroy
|
|
69
70
|
@notice = Alchemy.t("Successfully deleted element") % { element: @element.display_name }
|
|
70
71
|
end
|
|
@@ -90,10 +91,14 @@ module Alchemy
|
|
|
90
91
|
end
|
|
91
92
|
end
|
|
92
93
|
|
|
94
|
+
# Toggle fodls the element and persists the state in the db
|
|
95
|
+
#
|
|
96
|
+
# Ingredient validations might make the element invalid.
|
|
97
|
+
# In this case we are just toggling a UI state and do not care about the validations.
|
|
93
98
|
def fold
|
|
94
99
|
@page = @element.page
|
|
95
100
|
@element.folded = !@element.folded
|
|
96
|
-
@element.save
|
|
101
|
+
@element.save(validate: false)
|
|
97
102
|
end
|
|
98
103
|
|
|
99
104
|
private
|
|
@@ -26,7 +26,7 @@ module Alchemy
|
|
|
26
26
|
# @return Array<Alchemy::IngredientEditor>
|
|
27
27
|
def ingredients
|
|
28
28
|
element.definition.fetch(:ingredients, []).map do |ingredient|
|
|
29
|
-
Alchemy::IngredientEditor.new(find_or_create_ingredient(ingredient
|
|
29
|
+
Alchemy::IngredientEditor.new(find_or_create_ingredient(ingredient))
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -121,9 +121,12 @@ module Alchemy
|
|
|
121
121
|
Alchemy::Content.create(element: element, name: name)
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
def find_or_create_ingredient(
|
|
125
|
-
element.ingredients.
|
|
126
|
-
|
|
124
|
+
def find_or_create_ingredient(definition)
|
|
125
|
+
element.ingredients.detect { |i| i.role == definition[:role] } ||
|
|
126
|
+
element.ingredients.create!(
|
|
127
|
+
role: definition[:role],
|
|
128
|
+
type: Alchemy::Ingredient.normalize_type(definition[:type]),
|
|
129
|
+
)
|
|
127
130
|
end
|
|
128
131
|
end
|
|
129
132
|
end
|
|
@@ -64,8 +64,12 @@ module Alchemy
|
|
|
64
64
|
"element[ingredients_attributes][#{form_field_counter}][#{column}]"
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
# Returns a unique string to be passed to a form field id.
|
|
68
|
+
#
|
|
69
|
+
# @param column [String] A Ingredient column_name. Default is 'value'
|
|
70
|
+
#
|
|
67
71
|
def form_field_id(column = "value")
|
|
68
|
-
"
|
|
72
|
+
"element_#{element.id}_ingredient_#{id}_#{column}"
|
|
69
73
|
end
|
|
70
74
|
|
|
71
75
|
# Fixes Rails partial renderer calling to_model on the object
|
|
@@ -51,21 +51,23 @@ module Alchemy
|
|
|
51
51
|
# If the element uses +ingredients+ it returns the +value+ of the ingredient record.
|
|
52
52
|
#
|
|
53
53
|
def ingredient(name)
|
|
54
|
-
element.ingredient(name)
|
|
54
|
+
element.ingredient(name)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
deprecate ingredient: :value, deprecator: Alchemy::Deprecation
|
|
58
|
-
|
|
59
57
|
# Returns the value of one of the element's ingredients.
|
|
60
58
|
#
|
|
61
59
|
def value(name)
|
|
62
|
-
element.
|
|
60
|
+
element.value_for(name)
|
|
63
61
|
end
|
|
64
62
|
|
|
65
|
-
# Returns true if the given content or ingredient has
|
|
63
|
+
# Returns true if the given content or ingredient has a value.
|
|
66
64
|
#
|
|
67
65
|
def has?(name)
|
|
68
|
-
|
|
66
|
+
if element.ingredient_definitions.any?
|
|
67
|
+
element.has_value_for?(name)
|
|
68
|
+
else
|
|
69
|
+
element.has_ingredient?(name)
|
|
70
|
+
end
|
|
69
71
|
end
|
|
70
72
|
|
|
71
73
|
# Return's the given content's essence.
|
|
@@ -75,6 +77,12 @@ module Alchemy
|
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
deprecate essence: "Use `ingredient_by_role` instead", deprecator: Alchemy::Deprecation
|
|
80
|
+
|
|
81
|
+
# Return's the ingredient record by given role.
|
|
82
|
+
#
|
|
83
|
+
def ingredient_by_role(role)
|
|
84
|
+
element.ingredient_by_role(role)
|
|
85
|
+
end
|
|
78
86
|
end
|
|
79
87
|
|
|
80
88
|
# Block-level helper for element views. Constructs a DOM element wrapping
|
|
@@ -5,10 +5,20 @@ module Alchemy
|
|
|
5
5
|
module ElementEssences
|
|
6
6
|
# Returns the contents essence value (aka. ingredient) for passed content name.
|
|
7
7
|
def ingredient(name)
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
ing = ingredient_by_role(name)
|
|
9
|
+
if ing
|
|
10
|
+
Alchemy::Deprecation.warn <<~WARN
|
|
11
|
+
Using `element.ingredient` to get the value of an ingredient is deprecated and will change in Alchemy 6.1
|
|
12
|
+
If you want to read the value of an elements ingredient please use `element.value_for(:ingredient_role)` instead.
|
|
13
|
+
The next version of Alchemy will return a `Alchemy::Ingredient` record instead.
|
|
14
|
+
WARN
|
|
15
|
+
ing.value
|
|
16
|
+
else
|
|
17
|
+
content = content_by_name(name)
|
|
18
|
+
return nil if content.blank?
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
content.ingredient
|
|
21
|
+
end
|
|
12
22
|
end
|
|
13
23
|
|
|
14
24
|
# True if the element has a content for given name,
|
|
@@ -16,6 +26,7 @@ module Alchemy
|
|
|
16
26
|
def has_ingredient?(name)
|
|
17
27
|
ingredient(name).present?
|
|
18
28
|
end
|
|
29
|
+
deprecate has_ingredient?: :has_value_for?, deprecator: Alchemy::Deprecation
|
|
19
30
|
|
|
20
31
|
# Returns all essence errors in the format of:
|
|
21
32
|
#
|
|
@@ -22,6 +22,11 @@ module Alchemy
|
|
|
22
22
|
validates_associated :ingredients, on: :update
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
# The value of an ingredient of the element by role
|
|
26
|
+
def value_for(role)
|
|
27
|
+
ingredient_by_role(role)&.value
|
|
28
|
+
end
|
|
29
|
+
|
|
25
30
|
# Find first ingredient from element by given role.
|
|
26
31
|
def ingredient_by_role(role)
|
|
27
32
|
ingredients.detect { |ingredient| ingredient.role == role.to_s }
|
|
@@ -87,7 +92,7 @@ module Alchemy
|
|
|
87
92
|
# True if the element has a ingredient for given name
|
|
88
93
|
# that has a non blank value.
|
|
89
94
|
def has_value_for?(role)
|
|
90
|
-
|
|
95
|
+
value_for(role).present?
|
|
91
96
|
end
|
|
92
97
|
|
|
93
98
|
# Ingredient validation error messages
|
|
@@ -167,8 +172,11 @@ module Alchemy
|
|
|
167
172
|
|
|
168
173
|
# Builds ingredients for this element as described in the +elements.yml+
|
|
169
174
|
def build_ingredients
|
|
170
|
-
|
|
171
|
-
|
|
175
|
+
ingredient_definitions.each do |attributes|
|
|
176
|
+
ingredients.build(
|
|
177
|
+
role: attributes[:role],
|
|
178
|
+
type: Alchemy::Ingredient.normalize_type(attributes[:type]),
|
|
179
|
+
)
|
|
172
180
|
end
|
|
173
181
|
end
|
|
174
182
|
end
|
|
@@ -99,12 +99,12 @@ module Alchemy
|
|
|
99
99
|
# The ingredient that's used for element's preview text.
|
|
100
100
|
#
|
|
101
101
|
# It tries to find one of element's ingredients that is defined +as_element_title+.
|
|
102
|
-
# Takes element's first ingredient if no ingredient is defined +as_element_title+.
|
|
102
|
+
# Takes element's first defined ingredient if no ingredient is defined +as_element_title+.
|
|
103
103
|
#
|
|
104
104
|
# @return (Alchemy::Ingredient)
|
|
105
105
|
#
|
|
106
106
|
def preview_ingredient
|
|
107
|
-
@_preview_ingredient ||= ingredients.detect(&:preview_ingredient?) ||
|
|
107
|
+
@_preview_ingredient ||= ingredients.detect(&:preview_ingredient?) || first_ingredient_by_definition
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
private
|
|
@@ -122,6 +122,13 @@ module Alchemy
|
|
|
122
122
|
def preview_text_from_preview_ingredient(maxlength)
|
|
123
123
|
preview_ingredient&.preview_text(maxlength)
|
|
124
124
|
end
|
|
125
|
+
|
|
126
|
+
def first_ingredient_by_definition
|
|
127
|
+
return if ingredient_definitions.empty?
|
|
128
|
+
|
|
129
|
+
role = ingredient_definitions.first["role"]
|
|
130
|
+
ingredients.detect { |ingredient| ingredient.role == role }
|
|
131
|
+
end
|
|
125
132
|
end
|
|
126
133
|
end
|
|
127
134
|
end
|
|
@@ -267,20 +267,6 @@ module Alchemy
|
|
|
267
267
|
"alchemy/elements/#{name}"
|
|
268
268
|
end
|
|
269
269
|
|
|
270
|
-
# Returns the key that's taken for cache path.
|
|
271
|
-
#
|
|
272
|
-
# Uses the page's +published_at+ value that's updated when the user publishes the page.
|
|
273
|
-
#
|
|
274
|
-
# If the page is the current preview it uses the element's updated_at value as cache key.
|
|
275
|
-
#
|
|
276
|
-
def cache_key
|
|
277
|
-
if Page.current_preview == page
|
|
278
|
-
"alchemy/elements/#{id}-#{updated_at}"
|
|
279
|
-
else
|
|
280
|
-
"alchemy/elements/#{id}-#{page.published_at}"
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
|
|
284
270
|
# A collection of element names that can be nested inside this element.
|
|
285
271
|
def nestable_elements
|
|
286
272
|
definition.fetch("nestable_elements", [])
|
|
@@ -6,12 +6,13 @@ module Alchemy
|
|
|
6
6
|
|
|
7
7
|
include Hints
|
|
8
8
|
|
|
9
|
-
self.abstract_class = true
|
|
10
9
|
self.table_name = "alchemy_ingredients"
|
|
11
10
|
|
|
12
11
|
belongs_to :element, touch: true, class_name: "Alchemy::Element", inverse_of: :ingredients
|
|
13
12
|
belongs_to :related_object, polymorphic: true, optional: true
|
|
14
13
|
|
|
14
|
+
before_validation(on: :create) { self.value ||= default_value }
|
|
15
|
+
|
|
15
16
|
validates :type, presence: true
|
|
16
17
|
validates :role, presence: true
|
|
17
18
|
|
|
@@ -33,32 +34,6 @@ module Alchemy
|
|
|
33
34
|
scope :videos, -> { where(type: "Alchemy::Ingredients::Video") }
|
|
34
35
|
|
|
35
36
|
class << self
|
|
36
|
-
# Builds concrete ingredient class as described in the +elements.yml+
|
|
37
|
-
def build(attributes = {})
|
|
38
|
-
element = attributes[:element]
|
|
39
|
-
raise ArgumentError, "No element given. Please pass element in attributes." if element.nil?
|
|
40
|
-
raise ArgumentError, "No role given. Please pass role in attributes." if attributes[:role].nil?
|
|
41
|
-
|
|
42
|
-
definition = element.ingredient_definition_for(attributes[:role])
|
|
43
|
-
if definition.nil?
|
|
44
|
-
raise DefinitionError,
|
|
45
|
-
"No definition found for #{attributes[:role]}. Please define #{attributes[:role]} on #{element[:name]}."
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
ingredient_class = Ingredient.ingredient_class_by_type(definition[:type])
|
|
49
|
-
ingredient_class.new(
|
|
50
|
-
type: Ingredient.normalize_type(definition[:type]),
|
|
51
|
-
value: default_value(definition),
|
|
52
|
-
role: definition[:role],
|
|
53
|
-
element: element,
|
|
54
|
-
)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Creates concrete ingredient class as described in the +elements.yml+
|
|
58
|
-
def create(attributes = {})
|
|
59
|
-
build(attributes).tap(&:save)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
37
|
# Defines getter and setter method aliases for related object
|
|
63
38
|
#
|
|
64
39
|
# @param [String|Symbol] The name of the alias
|
|
@@ -78,20 +53,6 @@ module Alchemy
|
|
|
78
53
|
end
|
|
79
54
|
end
|
|
80
55
|
|
|
81
|
-
# Returns an ingredient class by type
|
|
82
|
-
#
|
|
83
|
-
# Raises ArgumentError if there is no such class in the
|
|
84
|
-
# +Alchemy::Ingredients+ module namespace.
|
|
85
|
-
#
|
|
86
|
-
# If you add custom ingredient class,
|
|
87
|
-
# put them in the +Alchemy::Ingredients+ module namespace
|
|
88
|
-
#
|
|
89
|
-
# @param [String] The ingredient class name to constantize
|
|
90
|
-
# @return [Class]
|
|
91
|
-
def ingredient_class_by_type(ingredient_type)
|
|
92
|
-
Alchemy::Ingredients.const_get(ingredient_type.to_s.classify.demodulize)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
56
|
# Modulize ingredient type
|
|
96
57
|
#
|
|
97
58
|
# Makes sure the passed ingredient type is in the +Alchemy::Ingredients+
|
|
@@ -112,22 +73,6 @@ module Alchemy
|
|
|
112
73
|
default: Alchemy.t("ingredient_roles.#{role}", default: role.humanize),
|
|
113
74
|
)
|
|
114
75
|
end
|
|
115
|
-
|
|
116
|
-
private
|
|
117
|
-
|
|
118
|
-
# Returns the default value from ingredient definition
|
|
119
|
-
#
|
|
120
|
-
# If the value is a symbol it gets passed through i18n
|
|
121
|
-
# inside the +alchemy.default_ingredient_texts+ scope
|
|
122
|
-
def default_value(definition)
|
|
123
|
-
default = definition[:default]
|
|
124
|
-
case default
|
|
125
|
-
when Symbol
|
|
126
|
-
Alchemy.t(default, scope: :default_ingredient_texts)
|
|
127
|
-
else
|
|
128
|
-
default
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
76
|
end
|
|
132
77
|
|
|
133
78
|
# Compatibility method for access from element
|
|
@@ -173,11 +118,6 @@ module Alchemy
|
|
|
173
118
|
value.to_s[0..maxlength - 1]
|
|
174
119
|
end
|
|
175
120
|
|
|
176
|
-
# Cross DB adapter data accessor that works
|
|
177
|
-
def data
|
|
178
|
-
@_data ||= (self[:data] || {}).with_indifferent_access
|
|
179
|
-
end
|
|
180
|
-
|
|
181
121
|
# The path to the view partial of the ingredient
|
|
182
122
|
# @return [String]
|
|
183
123
|
def to_partial_path
|
|
@@ -220,5 +160,19 @@ module Alchemy
|
|
|
220
160
|
def hint_translation_attribute
|
|
221
161
|
role
|
|
222
162
|
end
|
|
163
|
+
|
|
164
|
+
# Returns the default value from ingredient definition
|
|
165
|
+
#
|
|
166
|
+
# If the value is a symbol it gets passed through i18n
|
|
167
|
+
# inside the +alchemy.default_ingredient_texts+ scope
|
|
168
|
+
def default_value
|
|
169
|
+
default = definition[:default]
|
|
170
|
+
case default
|
|
171
|
+
when Symbol
|
|
172
|
+
Alchemy.t(default, scope: :default_ingredient_texts)
|
|
173
|
+
else
|
|
174
|
+
default
|
|
175
|
+
end
|
|
176
|
+
end
|
|
223
177
|
end
|
|
224
178
|
end
|
|
@@ -110,22 +110,13 @@ module Alchemy
|
|
|
110
110
|
# If the page is the current preview it uses the updated_at value as cache key.
|
|
111
111
|
#
|
|
112
112
|
def cache_key
|
|
113
|
-
if Page.current_preview ==
|
|
113
|
+
if Page.current_preview == id
|
|
114
114
|
"alchemy/pages/#{id}-#{updated_at}"
|
|
115
115
|
else
|
|
116
116
|
"alchemy/pages/#{id}-#{published_at}"
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
# We use the published_at value for the cache_key.
|
|
121
|
-
#
|
|
122
|
-
# If no published_at value is set yet, i.e. because it was never published,
|
|
123
|
-
# we return the updated_at value.
|
|
124
|
-
#
|
|
125
|
-
def published_at
|
|
126
|
-
read_attribute(:published_at) || updated_at
|
|
127
|
-
end
|
|
128
|
-
|
|
129
120
|
# Returns true if the page cache control headers should be set.
|
|
130
121
|
#
|
|
131
122
|
# == Disable Alchemy's page caching globally
|
data/app/models/alchemy/page.rb
CHANGED
|
@@ -198,13 +198,13 @@ module Alchemy
|
|
|
198
198
|
%w[name urlname title]
|
|
199
199
|
end
|
|
200
200
|
|
|
201
|
-
# Used to store the current page previewed in the edit page template.
|
|
201
|
+
# Used to store the current page id previewed in the edit page template.
|
|
202
202
|
#
|
|
203
203
|
def current_preview=(page)
|
|
204
|
-
RequestStore.store[:alchemy_current_preview] = page
|
|
204
|
+
RequestStore.store[:alchemy_current_preview] = page&.id
|
|
205
205
|
end
|
|
206
206
|
|
|
207
|
-
# Returns the current page previewed in the edit page template.
|
|
207
|
+
# Returns the current page id previewed in the edit page template.
|
|
208
208
|
#
|
|
209
209
|
def current_preview
|
|
210
210
|
RequestStore.store[:alchemy_current_preview]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Alchemy
|
|
4
4
|
class PageVersion < BaseRecord
|
|
5
|
-
belongs_to :page, class_name: "Alchemy::Page", inverse_of: :versions
|
|
5
|
+
belongs_to :page, class_name: "Alchemy::Page", inverse_of: :versions, touch: true
|
|
6
6
|
|
|
7
7
|
has_many :elements, -> { order(:position) },
|
|
8
8
|
class_name: "Alchemy::Element",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
Alchemy.growl('<%= Alchemy.t(:successfully_added_element) %>');
|
|
36
36
|
Alchemy.closeCurrentDialog();
|
|
37
|
-
Alchemy.Tinymce.init(<%= @element.richtext_contents_ids.to_json %>);
|
|
37
|
+
Alchemy.Tinymce.init(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>);
|
|
38
38
|
Alchemy.PreviewWindow.refresh(function() {
|
|
39
39
|
Alchemy.ElementEditors.focusElementPreview(<%= @element.id %>);
|
|
40
40
|
});
|
|
@@ -3,9 +3,7 @@ $('#element_<%= @element.id %>').hide(200, function() {
|
|
|
3
3
|
Alchemy.growl('<%= j @notice %>');
|
|
4
4
|
$('#element_area .sortable-elements').sortable('refresh');
|
|
5
5
|
Alchemy.PreviewWindow.refresh();
|
|
6
|
-
|
|
7
|
-
tinymce.get('tinymce_<%= id %>').remove();
|
|
8
|
-
<% end %>
|
|
6
|
+
Alchemy.Tinymce.remove(<%= @richtext_ids.to_json %>);
|
|
9
7
|
<% if @element.fixed? %>
|
|
10
8
|
Alchemy.FixedElements.removeTab(<%= @element.id %>);
|
|
11
9
|
<% end %>
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
<% if @element.folded? -%>
|
|
16
16
|
|
|
17
|
-
Alchemy.Tinymce.remove(<%= @element.richtext_contents_ids.to_json %>);
|
|
17
|
+
Alchemy.Tinymce.remove(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>);
|
|
18
18
|
|
|
19
19
|
<% else -%>
|
|
20
20
|
|
|
21
21
|
$el.trigger('FocusElementEditor.Alchemy');
|
|
22
|
-
Alchemy.Tinymce.init(<%= @element.richtext_contents_ids.to_json %>);
|
|
22
|
+
Alchemy.Tinymce.init(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>);
|
|
23
23
|
Alchemy.GUI.initElement($el);
|
|
24
24
|
Alchemy.SortableElements(
|
|
25
25
|
<%= @page.id %>,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
var $el = $('#element_<%= @element.id %>');
|
|
3
3
|
var $errors = $('#element_<%= @element.id %>_errors');
|
|
4
|
-
$('> .element-content .content_editor, > .element-content .
|
|
4
|
+
$('> .element-content .content_editor, > .element-content .ingredient-editor', $el).removeClass('validation_failed');
|
|
5
5
|
|
|
6
6
|
<%- if @element_validated -%>
|
|
7
7
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
data: boolean_editor.data_attributes do %>
|
|
4
4
|
<%= element_form.fields_for(:ingredients, boolean_editor.ingredient) do |f| %>
|
|
5
5
|
<%= f.label :value, style: "display: inline-block" do %>
|
|
6
|
-
<%= f.check_box :value %>
|
|
6
|
+
<%= f.check_box :value, id: nil %>
|
|
7
7
|
<%= render_ingredient_role(boolean_editor) %>
|
|
8
8
|
<% end %>
|
|
9
9
|
<%= render_hint_for(boolean_editor) %>
|
|
@@ -44,7 +44,9 @@
|
|
|
44
44
|
},
|
|
45
45
|
title: Alchemy.t(:edit_file_properties) %>
|
|
46
46
|
</div>
|
|
47
|
-
<%= f.hidden_field :attachment_id,
|
|
47
|
+
<%= f.hidden_field :attachment_id,
|
|
48
|
+
value: file_editor.attachment&.id,
|
|
49
|
+
id: file_editor.form_field_id(:attachment_id) %>
|
|
48
50
|
</div>
|
|
49
51
|
<% end %>
|
|
50
52
|
<% end %>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
data: headline_editor.data_attributes do %>
|
|
4
4
|
<%= element_form.fields_for(:ingredients, headline_editor.ingredient) do |f| %>
|
|
5
5
|
<%= ingredient_label(headline_editor) %>
|
|
6
|
-
<%= f.text_field :value %>
|
|
6
|
+
<%= f.text_field :value, id: nil %>
|
|
7
7
|
|
|
8
8
|
<div class="input-row">
|
|
9
9
|
<% if headline_editor.level_options.length > 1 %>
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
<%= element_form.fields_for(:ingredients, link_editor.ingredient) do |f| %>
|
|
5
5
|
<%= ingredient_label(link_editor) %>
|
|
6
6
|
<%= f.text_field :value,
|
|
7
|
-
class: "thin_border text_with_icon
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
class: "thin_border text_with_icon readonly",
|
|
8
|
+
id: link_editor.form_field_id,
|
|
9
|
+
"data-link-value": true,
|
|
10
|
+
readonly: true,
|
|
11
|
+
tabindex: -1
|
|
11
12
|
%>
|
|
12
|
-
<%= f.hidden_field :
|
|
13
|
-
<%= f.hidden_field :
|
|
14
|
-
<%= f.hidden_field :
|
|
15
|
-
<%= f.hidden_field :link_target, "data-link-target": true %>
|
|
13
|
+
<%= f.hidden_field :link_title, "data-link-title": true, id: nil %>
|
|
14
|
+
<%= f.hidden_field :link_class_name, "data-link-class": true, id: nil %>
|
|
15
|
+
<%= f.hidden_field :link_target, "data-link-target": true, id: nil %>
|
|
16
16
|
<% end %>
|
|
17
17
|
<%= render "alchemy/ingredients/shared/link_tools", ingredient_editor: link_editor %>
|
|
18
18
|
<% end %>
|
|
@@ -44,16 +44,17 @@
|
|
|
44
44
|
</div>
|
|
45
45
|
<% end %>
|
|
46
46
|
<%= f.hidden_field :picture_id, value: picture_editor.picture&.id,
|
|
47
|
+
id: picture_editor.form_field_id(:picture_id),
|
|
47
48
|
data: {
|
|
48
49
|
picture_id: true,
|
|
49
50
|
image_file_width: picture_editor.image_file_width,
|
|
50
51
|
image_file_height: picture_editor.image_file_height
|
|
51
52
|
} %>
|
|
52
|
-
<%= f.hidden_field :link, data: { link_value: true } %>
|
|
53
|
-
<%= f.hidden_field :link_title, data: { link_title: true } %>
|
|
54
|
-
<%= f.hidden_field :link_class_name, data: { link_class: true } %>
|
|
55
|
-
<%= f.hidden_field :link_target, data: { link_target: true } %>
|
|
56
|
-
<%= f.hidden_field :crop_from, data: { crop_from: true } %>
|
|
57
|
-
<%= f.hidden_field :crop_size, data: { crop_size: true } %>
|
|
53
|
+
<%= f.hidden_field :link, data: { link_value: true }, id: nil %>
|
|
54
|
+
<%= f.hidden_field :link_title, data: { link_title: true }, id: nil %>
|
|
55
|
+
<%= f.hidden_field :link_class_name, data: { link_class: true }, id: nil %>
|
|
56
|
+
<%= f.hidden_field :link_target, data: { link_target: true }, id: nil %>
|
|
57
|
+
<%= f.hidden_field :crop_from, data: { crop_from: true }, id: nil %>
|
|
58
|
+
<%= f.hidden_field :crop_size, data: { crop_size: true }, id: nil %>
|
|
58
59
|
<% end %>
|
|
59
60
|
<% end %>
|
|
@@ -7,12 +7,13 @@
|
|
|
7
7
|
<%= ingredient_label(text_editor) %>
|
|
8
8
|
<%= f.text_field :value,
|
|
9
9
|
class: text_editor.settings[:linkable] ? "text_with_icon" : "",
|
|
10
|
+
id: nil,
|
|
10
11
|
type: text_editor.settings[:input_type] || "text" %>
|
|
11
12
|
<% if text_editor.settings[:linkable] %>
|
|
12
|
-
<%= f.hidden_field :link, "data-link-value": true %>
|
|
13
|
-
<%= f.hidden_field :link_title, "data-link-title": true %>
|
|
14
|
-
<%= f.hidden_field :link_class_name, "data-link-class": true%>
|
|
15
|
-
<%= f.hidden_field :link_target, "data-link-target": true %>
|
|
13
|
+
<%= f.hidden_field :link, "data-link-value": true, id: nil %>
|
|
14
|
+
<%= f.hidden_field :link_title, "data-link-title": true, id: nil %>
|
|
15
|
+
<%= f.hidden_field :link_class_name, "data-link-class": true, id: nil %>
|
|
16
|
+
<%= f.hidden_field :link_target, "data-link-target": true, id: nil %>
|
|
16
17
|
<%= render "alchemy/ingredients/shared/link_tools", ingredient_editor: text_editor %>
|
|
17
18
|
<% end %>
|
|
18
19
|
<% end %>
|
|
@@ -16,7 +16,6 @@ RSpec.shared_examples_for "an alchemy ingredient" do
|
|
|
16
16
|
it { is_expected.to belong_to(:related_object).optional }
|
|
17
17
|
it { is_expected.to validate_presence_of(:role) }
|
|
18
18
|
it { is_expected.to validate_presence_of(:type) }
|
|
19
|
-
it { expect(subject.data).to eq({}) }
|
|
20
19
|
|
|
21
20
|
describe "#settings" do
|
|
22
21
|
subject { ingredient.settings }
|
data/lib/alchemy/tinymce.rb
CHANGED
|
@@ -34,6 +34,10 @@ module Alchemy
|
|
|
34
34
|
@@init
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
def custom_configs_present?(page)
|
|
38
|
+
custom_config_contents(page).any? || custom_config_ingredients(page).any?
|
|
39
|
+
end
|
|
40
|
+
|
|
37
41
|
def custom_config_contents(page)
|
|
38
42
|
content_definitions_from_elements(page.descendent_element_definitions)
|
|
39
43
|
end
|
|
@@ -30,7 +30,10 @@ module Alchemy::Upgrader::Tasks
|
|
|
30
30
|
next unless content
|
|
31
31
|
|
|
32
32
|
essence = content.essence
|
|
33
|
-
ingredient =
|
|
33
|
+
ingredient = element.ingredients.build(
|
|
34
|
+
role: ingredient_definition[:role],
|
|
35
|
+
type: Alchemy::Ingredient.normalize_type(ingredient_definition[:type]),
|
|
36
|
+
)
|
|
34
37
|
belongs_to_associations = essence.class.reflect_on_all_associations(:belongs_to)
|
|
35
38
|
if belongs_to_associations.any?
|
|
36
39
|
ingredient.related_object = essence.public_send(belongs_to_associations.first.name)
|
data/lib/alchemy/version.rb
CHANGED
data/package.json
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: alchemy_cms
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.0.0.
|
|
4
|
+
version: 6.0.0.pre.b6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas von Deyen
|
|
@@ -10,10 +10,10 @@ authors:
|
|
|
10
10
|
- Hendrik Mans
|
|
11
11
|
- Carsten Fregin
|
|
12
12
|
- Martin Meyerhoff
|
|
13
|
-
autorequire:
|
|
13
|
+
autorequire:
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
|
-
date: 2021-
|
|
16
|
+
date: 2021-09-02 00:00:00.000000000 Z
|
|
17
17
|
dependencies:
|
|
18
18
|
- !ruby/object:Gem::Dependency
|
|
19
19
|
name: actionmailer
|
|
@@ -1517,8 +1517,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
1517
1517
|
requirements:
|
|
1518
1518
|
- ImageMagick (libmagick), v6.6 or greater.
|
|
1519
1519
|
rubygems_version: 3.1.6
|
|
1520
|
-
signing_key:
|
|
1520
|
+
signing_key:
|
|
1521
1521
|
specification_version: 4
|
|
1522
1522
|
summary: A powerful, userfriendly and flexible CMS for Rails
|
|
1523
1523
|
test_files: []
|
|
1524
|
-
...
|