alchemy-json_api 0.15.0 → 0.23.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -0
- data/app/controllers/alchemy/json_api/admin/layout_pages_controller.rb +1 -1
- data/app/controllers/alchemy/json_api/admin/pages_controller.rb +17 -0
- data/app/controllers/alchemy/json_api/layout_pages_controller.rb +1 -1
- data/app/controllers/alchemy/json_api/pages_controller.rb +47 -16
- data/app/serializers/alchemy/json_api/element_serializer.rb +7 -0
- data/app/serializers/alchemy/json_api/essence_audio_serializer.rb +40 -0
- data/app/serializers/alchemy/json_api/essence_headline_serializer.rb +13 -0
- data/app/serializers/alchemy/json_api/essence_video_serializer.rb +42 -0
- data/app/serializers/alchemy/json_api/ingredient_audio_serializer.rb +40 -0
- data/app/serializers/alchemy/json_api/ingredient_boolean_serializer.rb +11 -0
- data/app/serializers/alchemy/json_api/ingredient_datetime_serializer.rb +11 -0
- data/app/serializers/alchemy/json_api/ingredient_file_serializer.rb +35 -0
- data/app/serializers/alchemy/json_api/ingredient_headline_serializer.rb +13 -0
- data/app/serializers/alchemy/json_api/ingredient_html_serializer.rb +11 -0
- data/app/serializers/alchemy/json_api/ingredient_link_serializer.rb +17 -0
- data/app/serializers/alchemy/json_api/ingredient_node_serializer.rb +35 -0
- data/app/serializers/alchemy/json_api/ingredient_page_serializer.rb +25 -0
- data/app/serializers/alchemy/json_api/ingredient_picture_serializer.rb +60 -0
- data/app/serializers/alchemy/json_api/ingredient_richtext_serializer.rb +18 -0
- data/app/serializers/alchemy/json_api/ingredient_select_serializer.rb +11 -0
- data/app/serializers/alchemy/json_api/ingredient_text_serializer.rb +22 -0
- data/app/serializers/alchemy/json_api/ingredient_video_serializer.rb +42 -0
- data/app/serializers/alchemy/json_api/page_serializer.rb +3 -0
- data/lib/alchemy/json_api/ingredient_serializer.rb +22 -0
- data/lib/alchemy/json_api/test_support/ingredient_serializer_behaviour.rb +33 -0
- data/lib/alchemy/json_api/version.rb +1 -1
- metadata +25 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 286d51964dbcd1daa66ce3c6ab76c762c41929c65aa4c670bd5ab50e63761e06
|
4
|
+
data.tar.gz: e1d00037b288b60f6a482773675a2926f317b01c2f82492ad6b9f8ee82defd0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd1e2056c485b4de654de4196809f6c7b8e0cdbab027ceb814a7e8ab0e97ad8eb63fecd444caf21bc8aa9b46e1266716b3534ec07871769a42845d2b4220631b
|
7
|
+
data.tar.gz: 8303041d11e09785397f318a7371965f85f54955df255fae99c1fd1b558258a2519bd208b5b6171e15945f57c64958ee33045ad2e9ca4f19b2da60266f06bfda
|
data/Rakefile
CHANGED
@@ -20,6 +20,8 @@ task :test_setup do
|
|
20
20
|
system <<-SETUP.strip_heredoc
|
21
21
|
export RAILS_ENV=test && \
|
22
22
|
bin/rake db:environment:set db:drop && \
|
23
|
+
bin/rake gutentag:install:migrations && \
|
24
|
+
bin/rails g gutentag:migration_versions && \
|
23
25
|
bin/rake railties:install:migrations && \
|
24
26
|
bin/rails g alchemy:devise:install --force && \
|
25
27
|
bin/rake db:migrate
|
@@ -4,9 +4,26 @@ module Alchemy
|
|
4
4
|
module Admin
|
5
5
|
class PagesController < JsonApi::PagesController
|
6
6
|
prepend_before_action { authorize! :edit_content, Alchemy::Page }
|
7
|
+
before_action :set_current_preview, only: :show
|
7
8
|
|
8
9
|
private
|
9
10
|
|
11
|
+
def cache_duration
|
12
|
+
0
|
13
|
+
end
|
14
|
+
|
15
|
+
def caching_options
|
16
|
+
{ public: false, must_revalidate: true }
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_current_preview
|
20
|
+
Alchemy::Page.current_preview = @page
|
21
|
+
end
|
22
|
+
|
23
|
+
def last_modified_for(page)
|
24
|
+
page.updated_at
|
25
|
+
end
|
26
|
+
|
10
27
|
def page_version_type
|
11
28
|
:draft_version
|
12
29
|
end
|
@@ -3,26 +3,57 @@
|
|
3
3
|
module Alchemy
|
4
4
|
module JsonApi
|
5
5
|
class PagesController < JsonApi::BaseController
|
6
|
-
before_action :
|
6
|
+
before_action :load_page_for_cache_key, only: :show
|
7
7
|
|
8
8
|
def index
|
9
|
-
allowed = [:page_layout]
|
10
|
-
|
11
|
-
jsonapi_filter(page_scope, allowed) do |
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
allowed = [:page_layout, :urlname]
|
10
|
+
|
11
|
+
jsonapi_filter(page_scope, allowed) do |filtered_pages|
|
12
|
+
@pages = filtered_pages.result
|
13
|
+
if stale?(last_modified: @pages.maximum(:published_at), etag: @pages.max_by(&:cache_key)&.cache_key)
|
14
|
+
# Only load pages with all includes when browser cache is stale
|
15
|
+
jsonapi_filter(page_scope_with_includes, allowed) do |filtered|
|
16
|
+
# decorate with our page model that has a eager loaded elements collection
|
17
|
+
filtered_pages = filtered.result.map { |page| api_page(page) }
|
18
|
+
jsonapi_paginate(filtered_pages) do |paginated|
|
19
|
+
render jsonapi: paginated
|
20
|
+
end
|
21
|
+
end
|
16
22
|
end
|
17
23
|
end
|
24
|
+
|
25
|
+
expires_in cache_duration, { public: @pages.none?(&:restricted?) }.merge(caching_options)
|
18
26
|
end
|
19
27
|
|
20
28
|
def show
|
21
|
-
|
29
|
+
if stale?(last_modified: last_modified_for(@page), etag: @page.cache_key)
|
30
|
+
# Only load page with all includes when browser cache is stale
|
31
|
+
render jsonapi: api_page(load_page)
|
32
|
+
end
|
33
|
+
|
34
|
+
expires_in cache_duration, { public: !@page.restricted? }.merge(caching_options)
|
22
35
|
end
|
23
36
|
|
24
37
|
private
|
25
38
|
|
39
|
+
def cache_duration
|
40
|
+
ENV.fetch("ALCHEMY_JSON_API_CACHE_DURATION", 3).to_i.hours
|
41
|
+
end
|
42
|
+
|
43
|
+
def caching_options
|
44
|
+
{ must_revalidate: true }
|
45
|
+
end
|
46
|
+
|
47
|
+
# Get page w/o includes to get cache key
|
48
|
+
def load_page_for_cache_key
|
49
|
+
@page = page_scope.where(id: params[:path]).
|
50
|
+
or(page_scope.where(urlname: params[:path])).first!
|
51
|
+
end
|
52
|
+
|
53
|
+
def last_modified_for(page)
|
54
|
+
page.published_at
|
55
|
+
end
|
56
|
+
|
26
57
|
def jsonapi_meta(pages)
|
27
58
|
pagination = jsonapi_pagination_meta(pages)
|
28
59
|
|
@@ -38,20 +69,19 @@ module Alchemy
|
|
38
69
|
|
39
70
|
def load_page_by_id
|
40
71
|
return unless params[:path] =~ /\A\d+\z/
|
41
|
-
|
72
|
+
page_scope_with_includes.find_by(id: params[:path])
|
42
73
|
end
|
43
74
|
|
44
75
|
def load_page_by_urlname
|
45
|
-
|
76
|
+
page_scope_with_includes.find_by(urlname: params[:path])
|
46
77
|
end
|
47
78
|
|
48
79
|
def page_scope
|
49
|
-
|
80
|
+
base_page_scope.contentpages
|
50
81
|
end
|
51
82
|
|
52
83
|
def page_scope_with_includes
|
53
|
-
|
54
|
-
where(language: Language.current).
|
84
|
+
page_scope.
|
55
85
|
includes(
|
56
86
|
[
|
57
87
|
:legacy_urls,
|
@@ -61,6 +91,7 @@ module Alchemy
|
|
61
91
|
elements: [
|
62
92
|
:nested_elements,
|
63
93
|
{ contents: { essence: :ingredient_association } },
|
94
|
+
{ ingredients: :related_object },
|
64
95
|
],
|
65
96
|
},
|
66
97
|
},
|
@@ -79,9 +110,9 @@ module Alchemy
|
|
79
110
|
def base_page_scope
|
80
111
|
# cancancan is not able to merge our complex AR scopes for logged in users
|
81
112
|
if can?(:edit_content, ::Alchemy::Page)
|
82
|
-
Alchemy::
|
113
|
+
Alchemy::Language.current.pages.joins(page_version_type)
|
83
114
|
else
|
84
|
-
Alchemy::
|
115
|
+
Alchemy::Language.current.pages.published.joins(page_version_type)
|
85
116
|
end
|
86
117
|
end
|
87
118
|
|
@@ -12,6 +12,8 @@ module Alchemy
|
|
12
12
|
:updated_at,
|
13
13
|
)
|
14
14
|
|
15
|
+
cache_options store: Rails.cache, namespace: "alchemy-jsonapi"
|
16
|
+
|
15
17
|
attribute :deprecated do |element|
|
16
18
|
!!element.definition[:deprecated]
|
17
19
|
end
|
@@ -20,6 +22,11 @@ module Alchemy
|
|
20
22
|
element.contents.map(&:essence)
|
21
23
|
end
|
22
24
|
|
25
|
+
has_many :ingredients,
|
26
|
+
serializer: ->(record) do
|
27
|
+
"Alchemy::JsonApi::Ingredient#{record.type.demodulize}Serializer".constantize
|
28
|
+
end
|
29
|
+
|
23
30
|
has_many :nested_elements, record_type: :element, serializer: self
|
24
31
|
end
|
25
32
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/essence_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class EssenceAudioSerializer
|
8
|
+
include EssenceSerializer
|
9
|
+
|
10
|
+
attributes(
|
11
|
+
:autoplay,
|
12
|
+
:controls,
|
13
|
+
:muted,
|
14
|
+
:loop,
|
15
|
+
)
|
16
|
+
|
17
|
+
attribute :ingredient do |essence|
|
18
|
+
essence.attachment&.url
|
19
|
+
end
|
20
|
+
|
21
|
+
with_options if: ->(essence) { essence.attachment } do
|
22
|
+
attribute :audio_name do |essence|
|
23
|
+
essence.attachment.name
|
24
|
+
end
|
25
|
+
|
26
|
+
attribute :audio_file_name do |essence|
|
27
|
+
essence.attachment.file_name
|
28
|
+
end
|
29
|
+
|
30
|
+
attribute :audio_mime_type do |essence|
|
31
|
+
essence.attachment.file_mime_type
|
32
|
+
end
|
33
|
+
|
34
|
+
attribute :audio_file_size do |essence|
|
35
|
+
essence.attachment.file_size
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/essence_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class EssenceVideoSerializer
|
8
|
+
include EssenceSerializer
|
9
|
+
|
10
|
+
attributes(
|
11
|
+
:width,
|
12
|
+
:height,
|
13
|
+
:allow_fullscreen,
|
14
|
+
:autoplay,
|
15
|
+
:controls,
|
16
|
+
:preload,
|
17
|
+
)
|
18
|
+
|
19
|
+
attribute :ingredient do |essence|
|
20
|
+
essence.attachment&.url
|
21
|
+
end
|
22
|
+
|
23
|
+
with_options if: ->(essence) { essence.attachment } do
|
24
|
+
attribute :video_name do |essence|
|
25
|
+
essence.attachment.name
|
26
|
+
end
|
27
|
+
|
28
|
+
attribute :video_file_name do |essence|
|
29
|
+
essence.attachment.file_name
|
30
|
+
end
|
31
|
+
|
32
|
+
attribute :video_mime_type do |essence|
|
33
|
+
essence.attachment.file_mime_type
|
34
|
+
end
|
35
|
+
|
36
|
+
attribute :video_file_size do |essence|
|
37
|
+
essence.attachment.file_size
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientAudioSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attributes(
|
11
|
+
:autoplay,
|
12
|
+
:controls,
|
13
|
+
:muted,
|
14
|
+
:loop,
|
15
|
+
)
|
16
|
+
|
17
|
+
attribute :value do |ingredient|
|
18
|
+
ingredient.attachment&.url
|
19
|
+
end
|
20
|
+
|
21
|
+
with_options if: ->(ingredient) { ingredient.attachment } do
|
22
|
+
attribute :audio_name do |ingredient|
|
23
|
+
ingredient.attachment.name
|
24
|
+
end
|
25
|
+
|
26
|
+
attribute :audio_file_name do |ingredient|
|
27
|
+
ingredient.attachment.file_name
|
28
|
+
end
|
29
|
+
|
30
|
+
attribute :audio_mime_type do |ingredient|
|
31
|
+
ingredient.attachment.file_mime_type
|
32
|
+
end
|
33
|
+
|
34
|
+
attribute :audio_file_size do |ingredient|
|
35
|
+
ingredient.attachment.file_size
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientFileSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attribute :link_title, &:title
|
11
|
+
|
12
|
+
attribute :value do |ingredient|
|
13
|
+
ingredient.attachment&.url
|
14
|
+
end
|
15
|
+
|
16
|
+
with_options if: proc { |ingredient| ingredient.attachment } do
|
17
|
+
attribute :attachment_name do |ingredient|
|
18
|
+
ingredient.attachment.name
|
19
|
+
end
|
20
|
+
|
21
|
+
attribute :attachment_file_name do |ingredient|
|
22
|
+
ingredient.attachment.file_name
|
23
|
+
end
|
24
|
+
|
25
|
+
attribute :attachment_mime_type do |ingredient|
|
26
|
+
ingredient.attachment.file_mime_type
|
27
|
+
end
|
28
|
+
|
29
|
+
attribute :attachment_file_size do |ingredient|
|
30
|
+
ingredient.attachment.file_size
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientLinkSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attributes(
|
11
|
+
:link_class_name,
|
12
|
+
:link_target,
|
13
|
+
:link_title
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientNodeSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attribute :value do |ingredient|
|
11
|
+
ingredient.node&.name
|
12
|
+
end
|
13
|
+
|
14
|
+
belongs_to :node, record_type: :node, serializer: ::Alchemy::JsonApi::NodeSerializer
|
15
|
+
|
16
|
+
with_options if: proc { |ingredient| ingredient.node } do
|
17
|
+
attribute :name do |ingredient|
|
18
|
+
ingredient.node.name
|
19
|
+
end
|
20
|
+
|
21
|
+
attribute :link_url do |ingredient|
|
22
|
+
ingredient.node.url
|
23
|
+
end
|
24
|
+
|
25
|
+
attribute :link_title do |ingredient|
|
26
|
+
ingredient.node.title
|
27
|
+
end
|
28
|
+
|
29
|
+
attribute :link_nofollow do |ingredient|
|
30
|
+
ingredient.node.nofollow
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientPageSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attribute :value do |ingredient|
|
11
|
+
ingredient.page&.url_path
|
12
|
+
end
|
13
|
+
|
14
|
+
attribute :page_name do |ingredient|
|
15
|
+
ingredient.page&.name
|
16
|
+
end
|
17
|
+
|
18
|
+
attribute :page_url do |ingredient|
|
19
|
+
ingredient.page&.url_path
|
20
|
+
end
|
21
|
+
|
22
|
+
has_one :page, record_type: :page, serializer: ::Alchemy::JsonApi::PageSerializer
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientPictureSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attributes(
|
11
|
+
:title,
|
12
|
+
:caption,
|
13
|
+
:link_class_name,
|
14
|
+
:link_title,
|
15
|
+
:link_target,
|
16
|
+
)
|
17
|
+
|
18
|
+
attribute :value do |ingredient|
|
19
|
+
ingredient.picture&.url
|
20
|
+
end
|
21
|
+
|
22
|
+
attribute :alt_text, &:alt_tag
|
23
|
+
attribute :link_url, &:link
|
24
|
+
|
25
|
+
with_options if: proc { |ingredient| ingredient.picture.present? } do
|
26
|
+
attribute :image_dimensions do |ingredient|
|
27
|
+
sizes = ingredient.settings[:size]&.split("x", 2)&.map(&:to_i) || [
|
28
|
+
ingredient.image_file_width,
|
29
|
+
ingredient.image_file_height,
|
30
|
+
]
|
31
|
+
|
32
|
+
ratio = ingredient.image_file_width.to_f / ingredient.image_file_height
|
33
|
+
width = sizes[0].zero? ? sizes[1] * ratio : sizes[0]
|
34
|
+
height = sizes[1].zero? ? sizes[0] / ratio : sizes[1]
|
35
|
+
|
36
|
+
{
|
37
|
+
width: width,
|
38
|
+
height: height,
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
attribute :image_name do |ingredient|
|
43
|
+
ingredient.picture.name
|
44
|
+
end
|
45
|
+
|
46
|
+
attribute :image_file_name do |ingredient|
|
47
|
+
ingredient.picture.image_file_name
|
48
|
+
end
|
49
|
+
|
50
|
+
attribute :image_mime_type do |ingredient|
|
51
|
+
"image/#{ingredient.picture.image_file_format}"
|
52
|
+
end
|
53
|
+
|
54
|
+
attribute :image_file_size do |ingredient|
|
55
|
+
ingredient.picture.image_file_size
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientRichtextSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attributes(
|
11
|
+
:sanitized_body,
|
12
|
+
:stripped_body,
|
13
|
+
)
|
14
|
+
|
15
|
+
attribute :body, &:value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientTextSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attributes(
|
11
|
+
:link,
|
12
|
+
:link_class_name,
|
13
|
+
:link_target,
|
14
|
+
:link_title,
|
15
|
+
)
|
16
|
+
|
17
|
+
# maintain compatibility with EssenceText
|
18
|
+
attribute :body, &:value
|
19
|
+
attribute :link_url, &:link
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "alchemy/json_api/ingredient_serializer"
|
4
|
+
|
5
|
+
module Alchemy
|
6
|
+
module JsonApi
|
7
|
+
class IngredientVideoSerializer
|
8
|
+
include IngredientSerializer
|
9
|
+
|
10
|
+
attributes(
|
11
|
+
:width,
|
12
|
+
:height,
|
13
|
+
:allow_fullscreen,
|
14
|
+
:autoplay,
|
15
|
+
:controls,
|
16
|
+
:preload,
|
17
|
+
)
|
18
|
+
|
19
|
+
attribute :value do |ingredient|
|
20
|
+
ingredient.attachment&.url
|
21
|
+
end
|
22
|
+
|
23
|
+
with_options if: ->(ingredient) { ingredient.attachment } do
|
24
|
+
attribute :video_name do |ingredient|
|
25
|
+
ingredient.attachment.name
|
26
|
+
end
|
27
|
+
|
28
|
+
attribute :video_file_name do |ingredient|
|
29
|
+
ingredient.attachment.file_name
|
30
|
+
end
|
31
|
+
|
32
|
+
attribute :video_mime_type do |ingredient|
|
33
|
+
ingredient.attachment.file_mime_type
|
34
|
+
end
|
35
|
+
|
36
|
+
attribute :video_file_size do |ingredient|
|
37
|
+
ingredient.attachment.file_size
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -9,6 +9,7 @@ module Alchemy
|
|
9
9
|
attributes(
|
10
10
|
:name,
|
11
11
|
:urlname,
|
12
|
+
:url_path,
|
12
13
|
:page_layout,
|
13
14
|
:title,
|
14
15
|
:language_code,
|
@@ -18,6 +19,8 @@ module Alchemy
|
|
18
19
|
:updated_at,
|
19
20
|
)
|
20
21
|
|
22
|
+
cache_options store: Rails.cache, namespace: "alchemy-jsonapi"
|
23
|
+
|
21
24
|
attribute :legacy_urls do |page|
|
22
25
|
page.legacy_urls.map(&:urlname)
|
23
26
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
module JsonApi
|
5
|
+
module IngredientSerializer
|
6
|
+
def self.included(klass)
|
7
|
+
klass.include JSONAPI::Serializer
|
8
|
+
|
9
|
+
klass.has_one :element, record_type: :element, serializer: ::Alchemy::JsonApi::ElementSerializer
|
10
|
+
|
11
|
+
klass.attributes(
|
12
|
+
:role,
|
13
|
+
:value,
|
14
|
+
:created_at,
|
15
|
+
:updated_at
|
16
|
+
)
|
17
|
+
|
18
|
+
klass.attribute :deprecated, &:deprecated?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_examples "an ingredient serializer" do
|
4
|
+
describe "attributes" do
|
5
|
+
subject { serializer.serializable_hash[:data][:attributes] }
|
6
|
+
|
7
|
+
it "has the right keys and values" do
|
8
|
+
expect(subject).to have_key(:role)
|
9
|
+
expect(subject).to have_key(:value)
|
10
|
+
expect(subject).to have_key(:created_at)
|
11
|
+
expect(subject).to have_key(:updated_at)
|
12
|
+
expect(subject[:deprecated]).to be(false)
|
13
|
+
end
|
14
|
+
|
15
|
+
context "a deprecated ingredient" do
|
16
|
+
before do
|
17
|
+
expect(ingredient).to receive(:deprecated?) { true }
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has deprecated attribute set to true" do
|
21
|
+
expect(subject[:deprecated]).to eq(true)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "relationships" do
|
27
|
+
subject { serializer.serializable_hash[:data][:relationships] }
|
28
|
+
|
29
|
+
it "has one element" do
|
30
|
+
expect(subject[:element]).to eq(data: { id: ingredient.element_id.to_s, type: :element })
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alchemy-json_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Meyerhoff
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: alchemy_cms
|
@@ -131,9 +131,11 @@ files:
|
|
131
131
|
- app/controllers/alchemy/json_api/pages_controller.rb
|
132
132
|
- app/models/alchemy/json_api/page.rb
|
133
133
|
- app/serializers/alchemy/json_api/element_serializer.rb
|
134
|
+
- app/serializers/alchemy/json_api/essence_audio_serializer.rb
|
134
135
|
- app/serializers/alchemy/json_api/essence_boolean_serializer.rb
|
135
136
|
- app/serializers/alchemy/json_api/essence_date_serializer.rb
|
136
137
|
- app/serializers/alchemy/json_api/essence_file_serializer.rb
|
138
|
+
- app/serializers/alchemy/json_api/essence_headline_serializer.rb
|
137
139
|
- app/serializers/alchemy/json_api/essence_html_serializer.rb
|
138
140
|
- app/serializers/alchemy/json_api/essence_link_serializer.rb
|
139
141
|
- app/serializers/alchemy/json_api/essence_node_serializer.rb
|
@@ -142,6 +144,21 @@ files:
|
|
142
144
|
- app/serializers/alchemy/json_api/essence_richtext_serializer.rb
|
143
145
|
- app/serializers/alchemy/json_api/essence_select_serializer.rb
|
144
146
|
- app/serializers/alchemy/json_api/essence_text_serializer.rb
|
147
|
+
- app/serializers/alchemy/json_api/essence_video_serializer.rb
|
148
|
+
- app/serializers/alchemy/json_api/ingredient_audio_serializer.rb
|
149
|
+
- app/serializers/alchemy/json_api/ingredient_boolean_serializer.rb
|
150
|
+
- app/serializers/alchemy/json_api/ingredient_datetime_serializer.rb
|
151
|
+
- app/serializers/alchemy/json_api/ingredient_file_serializer.rb
|
152
|
+
- app/serializers/alchemy/json_api/ingredient_headline_serializer.rb
|
153
|
+
- app/serializers/alchemy/json_api/ingredient_html_serializer.rb
|
154
|
+
- app/serializers/alchemy/json_api/ingredient_link_serializer.rb
|
155
|
+
- app/serializers/alchemy/json_api/ingredient_node_serializer.rb
|
156
|
+
- app/serializers/alchemy/json_api/ingredient_page_serializer.rb
|
157
|
+
- app/serializers/alchemy/json_api/ingredient_picture_serializer.rb
|
158
|
+
- app/serializers/alchemy/json_api/ingredient_richtext_serializer.rb
|
159
|
+
- app/serializers/alchemy/json_api/ingredient_select_serializer.rb
|
160
|
+
- app/serializers/alchemy/json_api/ingredient_text_serializer.rb
|
161
|
+
- app/serializers/alchemy/json_api/ingredient_video_serializer.rb
|
145
162
|
- app/serializers/alchemy/json_api/language_serializer.rb
|
146
163
|
- app/serializers/alchemy/json_api/node_serializer.rb
|
147
164
|
- app/serializers/alchemy/json_api/page_serializer.rb
|
@@ -149,14 +166,16 @@ files:
|
|
149
166
|
- lib/alchemy/json_api.rb
|
150
167
|
- lib/alchemy/json_api/engine.rb
|
151
168
|
- lib/alchemy/json_api/essence_serializer.rb
|
169
|
+
- lib/alchemy/json_api/ingredient_serializer.rb
|
152
170
|
- lib/alchemy/json_api/test_support/essence_serializer_behaviour.rb
|
171
|
+
- lib/alchemy/json_api/test_support/ingredient_serializer_behaviour.rb
|
153
172
|
- lib/alchemy/json_api/version.rb
|
154
173
|
- lib/tasks/alchemy/json_api_tasks.rake
|
155
174
|
homepage: https://github.com/AlchemyCMS/alchemy-json_api
|
156
175
|
licenses:
|
157
176
|
- MIT
|
158
177
|
metadata: {}
|
159
|
-
post_install_message:
|
178
|
+
post_install_message:
|
160
179
|
rdoc_options: []
|
161
180
|
require_paths:
|
162
181
|
- lib
|
@@ -171,8 +190,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
190
|
- !ruby/object:Gem::Version
|
172
191
|
version: '0'
|
173
192
|
requirements: []
|
174
|
-
rubygems_version: 3.
|
175
|
-
signing_key:
|
193
|
+
rubygems_version: 3.2.26
|
194
|
+
signing_key:
|
176
195
|
specification_version: 4
|
177
196
|
summary: A JSONAPI compliant API for AlchemyCMS
|
178
197
|
test_files: []
|