alchemy-json_api 0.14.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -0
  3. data/app/controllers/alchemy/json_api/admin/layout_pages_controller.rb +1 -1
  4. data/app/controllers/alchemy/json_api/admin/pages_controller.rb +17 -0
  5. data/app/controllers/alchemy/json_api/layout_pages_controller.rb +1 -1
  6. data/app/controllers/alchemy/json_api/pages_controller.rb +47 -16
  7. data/app/serializers/alchemy/json_api/element_serializer.rb +7 -0
  8. data/app/serializers/alchemy/json_api/essence_audio_serializer.rb +40 -0
  9. data/app/serializers/alchemy/json_api/essence_headline_serializer.rb +13 -0
  10. data/app/serializers/alchemy/json_api/essence_picture_serializer.rb +13 -1
  11. data/app/serializers/alchemy/json_api/essence_video_serializer.rb +42 -0
  12. data/app/serializers/alchemy/json_api/ingredient_audio_serializer.rb +40 -0
  13. data/app/serializers/alchemy/json_api/ingredient_boolean_serializer.rb +11 -0
  14. data/app/serializers/alchemy/json_api/ingredient_datetime_serializer.rb +11 -0
  15. data/app/serializers/alchemy/json_api/ingredient_file_serializer.rb +35 -0
  16. data/app/serializers/alchemy/json_api/ingredient_headline_serializer.rb +13 -0
  17. data/app/serializers/alchemy/json_api/ingredient_html_serializer.rb +11 -0
  18. data/app/serializers/alchemy/json_api/ingredient_link_serializer.rb +17 -0
  19. data/app/serializers/alchemy/json_api/ingredient_node_serializer.rb +35 -0
  20. data/app/serializers/alchemy/json_api/ingredient_page_serializer.rb +25 -0
  21. data/app/serializers/alchemy/json_api/ingredient_picture_serializer.rb +60 -0
  22. data/app/serializers/alchemy/json_api/ingredient_richtext_serializer.rb +18 -0
  23. data/app/serializers/alchemy/json_api/ingredient_select_serializer.rb +11 -0
  24. data/app/serializers/alchemy/json_api/ingredient_text_serializer.rb +22 -0
  25. data/app/serializers/alchemy/json_api/ingredient_video_serializer.rb +42 -0
  26. data/app/serializers/alchemy/json_api/page_serializer.rb +3 -0
  27. data/lib/alchemy/json_api/ingredient_serializer.rb +22 -0
  28. data/lib/alchemy/json_api/test_support/ingredient_serializer_behaviour.rb +33 -0
  29. data/lib/alchemy/json_api/version.rb +1 -1
  30. metadata +22 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00a9cfebbdb1f42b95a9b199bb23b5690ba65ff21b14a95e260beff9dafe1d1e
4
- data.tar.gz: 0ce06ce3e137b56e40f5c8c08d895eb5f2eca7cc0936ed07c07cc2d6352530e5
3
+ metadata.gz: cae8005b1598184e56bb18b86ec302ef62b479275e6f0a07c320035e808a0d9b
4
+ data.tar.gz: f346c05c8e6f7b6dbf87366f755e376d94abf1db11748f2027197d81d30f24f8
5
5
  SHA512:
6
- metadata.gz: 87723e7055f3968a0a1d75b6d133e2fc0a3a8efeb5b61e222771e91c673e9313052a3e154280a01c2beaa9f49144c90da9ecb6d05282987943ea2e9d06b0de7b
7
- data.tar.gz: c2694da5d297f1acbbb16ed9a59858e5c84504091d430e82019e77aaae14549cb9b6e4d59ceee0a38b03e37f98162ea4881d2518e387b074cdd02e3c38bf8a1b
6
+ metadata.gz: 01200d6d1e6924208633453d4bef55e1a710563ec5dd0b6d95338e6ed71141c51ef4270ce70b9482c3774c94949bd143267c3a204d198f0f0cff21c38fc56055
7
+ data.tar.gz: ed765c1c38ec22e3c531fa314481d958c89d576c94a0496df52e64ca285c75129d1243ea9efad2a5ce75e232aa067802f134e93bb7318769477e82b7689490f6
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
@@ -6,7 +6,7 @@ module Alchemy
6
6
  private
7
7
 
8
8
  def page_scope
9
- page_scope_with_includes.layoutpages
9
+ base_page_scope.layoutpages
10
10
  end
11
11
  end
12
12
  end
@@ -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
@@ -5,7 +5,7 @@ module Alchemy
5
5
  private
6
6
 
7
7
  def page_scope
8
- page_scope_with_includes.layoutpages
8
+ base_page_scope.layoutpages
9
9
  end
10
10
  end
11
11
  end
@@ -3,26 +3,57 @@
3
3
  module Alchemy
4
4
  module JsonApi
5
5
  class PagesController < JsonApi::BaseController
6
- before_action :load_page, only: :show
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 |filtered|
12
- # decorate with our page model that has a eager loaded elements collection
13
- pages = filtered.result.map { |page| api_page(page) }
14
- jsonapi_paginate(pages) do |paginated|
15
- render jsonapi: paginated
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
- render jsonapi: api_page(@page)
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
- page_scope.find_by(id: params[:path])
72
+ page_scope_with_includes.find_by(id: params[:path])
42
73
  end
43
74
 
44
75
  def load_page_by_urlname
45
- page_scope.find_by(urlname: params[:path])
76
+ page_scope_with_includes.find_by(urlname: params[:path])
46
77
  end
47
78
 
48
79
  def page_scope
49
- page_scope_with_includes.contentpages
80
+ base_page_scope.contentpages
50
81
  end
51
82
 
52
83
  def page_scope_with_includes
53
- base_page_scope.
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::Page.all.joins(page_version_type)
113
+ Alchemy::Language.current.pages.joins(page_version_type)
83
114
  else
84
- Alchemy::Page.published.joins(page_version_type)
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,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "alchemy/json_api/essence_serializer"
4
+
5
+ module Alchemy
6
+ module JsonApi
7
+ class EssenceHeadlineSerializer
8
+ include EssenceSerializer
9
+
10
+ attributes :level, :size
11
+ end
12
+ end
13
+ end
@@ -18,7 +18,19 @@ module Alchemy
18
18
 
19
19
  with_options if: proc { |essence| essence.picture.present? } do
20
20
  attribute :image_dimensions do |essence|
21
- essence.sizes_from_string(essence.render_size)
21
+ sizes = essence.content.settings[:size]&.split("x", 2)&.map(&:to_i) || [
22
+ essence.image_file_width,
23
+ essence.image_file_height,
24
+ ]
25
+
26
+ ratio = essence.image_file_width.to_f / essence.image_file_height
27
+ width = sizes[0].zero? ? sizes[1] * ratio : sizes[0]
28
+ height = sizes[1].zero? ? sizes[0] / ratio : sizes[1]
29
+
30
+ {
31
+ width: width,
32
+ height: height,
33
+ }
22
34
  end
23
35
 
24
36
  attribute :image_name do |essence|
@@ -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,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "alchemy/json_api/ingredient_serializer"
4
+
5
+ module Alchemy
6
+ module JsonApi
7
+ class IngredientBooleanSerializer
8
+ include IngredientSerializer
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "alchemy/json_api/ingredient_serializer"
4
+
5
+ module Alchemy
6
+ module JsonApi
7
+ class IngredientDatetimeSerializer
8
+ include IngredientSerializer
9
+ end
10
+ end
11
+ 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,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "alchemy/json_api/ingredient_serializer"
4
+
5
+ module Alchemy
6
+ module JsonApi
7
+ class IngredientHeadlineSerializer
8
+ include IngredientSerializer
9
+
10
+ attributes :level, :size
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "alchemy/json_api/ingredient_serializer"
4
+
5
+ module Alchemy
6
+ module JsonApi
7
+ class IngredientHtmlSerializer
8
+ include IngredientSerializer
9
+ end
10
+ end
11
+ 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,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "alchemy/json_api/ingredient_serializer"
4
+
5
+ module Alchemy
6
+ module JsonApi
7
+ class IngredientSelectSerializer
8
+ include IngredientSerializer
9
+ end
10
+ end
11
+ 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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Alchemy
3
3
  module JsonApi
4
- VERSION = "0.14.0"
4
+ VERSION = "0.22.0"
5
5
  end
6
6
  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.14.0
4
+ version: 0.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Meyerhoff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-27 00:00:00.000000000 Z
11
+ date: 2021-10-25 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,7 +166,9 @@ 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
@@ -171,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
190
  - !ruby/object:Gem::Version
172
191
  version: '0'
173
192
  requirements: []
174
- rubygems_version: 3.1.6
193
+ rubygems_version: 3.2.26
175
194
  signing_key:
176
195
  specification_version: 4
177
196
  summary: A JSONAPI compliant API for AlchemyCMS