alchemy-json_api 0.14.0 → 0.22.0

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 (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