Skip to content

Commit 196f173

Browse files
committed
Add public theme palette endpoints
1 parent 218e001 commit 196f173

File tree

4 files changed

+185
-6
lines changed

4 files changed

+185
-6
lines changed

app/controllers/api_public/v1/theme_controller.rb

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,42 @@ def index
3939
I18n.locale = locale if locale.present?
4040

4141
website = Pwb::Current.website
42+
palette_id = params[:palette_id].presence
4243

4344
# Cache theme for 1 hour - changes infrequently
44-
etag_data = [website.id, website.updated_at, website.style_variables]
45+
etag_data = [website.id, website.updated_at, website.style_variables, palette_id]
4546
set_long_cache(max_age: 1.hour, etag_data: etag_data)
4647
return if performed?
4748

4849
render json: {
49-
theme: build_theme_response(website)
50+
theme: build_theme_response(website, palette_id: palette_id)
5051
}
5152
end
5253

5354
private
5455

55-
def build_theme_response(website)
56+
def build_theme_response(website, palette_id: nil)
57+
theme = website.current_theme
58+
palette_override = palette_id.present? && theme&.valid_palette?(palette_id) ? palette_id : nil
59+
base_vars = website.style_variables_for_theme&.dig("default") ||
60+
Pwb::WebsiteStyleable::DEFAULT_STYLE_VARIABLES.dup
61+
palette_colors = palette_override ? theme.palette_colors(palette_override) : nil
62+
colors = palette_colors.present? ? base_vars.merge(palette_colors) : website.style_variables
63+
css_variables = if palette_override && theme
64+
website.palette_loader.generate_full_css(theme.name, palette_override)
65+
else
66+
website.css_variables_with_dark_mode
67+
end
68+
5669
{
5770
name: website.theme_name || "default",
58-
palette_id: website.effective_palette_id,
71+
palette_id: palette_override || website.effective_palette_id,
5972
palette_mode: website.respond_to?(:palette_mode) ? (website.palette_mode || "dynamic") : "dynamic",
60-
colors: website.style_variables,
73+
colors: colors,
6174
fonts: extract_fonts(website),
6275
border_radius: extract_border_radius(website),
6376
dark_mode: build_dark_mode_config(website),
64-
css_variables: website.css_variables_with_dark_mode,
77+
css_variables: css_variables,
6578
custom_css: website.respond_to?(:raw_css) ? website.raw_css : nil,
6679
map_config: build_map_config(website)
6780
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# frozen_string_literal: true
2+
3+
module ApiPublic
4+
module V1
5+
# Public API endpoints for theme palettes
6+
# Lists available palettes and returns palette details for a theme
7+
class ThemePalettesController < BaseController
8+
include ApiPublic::Cacheable
9+
10+
# GET /api_public/v1/themes/:theme_name/palettes
11+
def index
12+
theme = find_theme
13+
return render_not_found unless theme
14+
15+
set_long_cache(max_age: 1.hour, etag_data: [theme.name, theme.palettes.keys])
16+
return if performed?
17+
18+
render json: {
19+
theme: theme.name,
20+
palettes: theme.list_palettes
21+
}
22+
end
23+
24+
# GET /api_public/v1/themes/:theme_name/palettes/:palette_id
25+
def show
26+
theme = find_theme
27+
return render_not_found unless theme
28+
29+
palette_id = params[:palette_id].to_s
30+
palette = theme.palette(palette_id)
31+
return render_palette_not_found unless palette
32+
33+
set_long_cache(max_age: 1.hour, etag_data: [theme.name, palette_id])
34+
return if performed?
35+
36+
render json: {
37+
theme: theme.name,
38+
palette: palette.merge(
39+
"css_variables" => theme.generate_palette_css(palette_id)
40+
)
41+
}
42+
end
43+
44+
private
45+
46+
def find_theme
47+
theme_name = params[:theme_name].to_s
48+
return nil if theme_name.blank?
49+
50+
Pwb::Theme.find_by(name: theme_name)
51+
end
52+
53+
def render_not_found
54+
render json: { error: "Theme not found" }, status: :not_found
55+
end
56+
57+
def render_palette_not_found
58+
render json: { error: "Palette not found" }, status: :not_found
59+
end
60+
end
61+
end
62+
end

config/routes.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,8 @@
729729
get "/site_details" => "site_details#index"
730730
get "/select_values" => "select_values#index"
731731
get "/theme" => "theme#index"
732+
get "/themes/:theme_name/palettes" => "theme_palettes#index"
733+
get "/themes/:theme_name/palettes/:palette_id" => "theme_palettes#show"
732734
get "/search/config" => "search_config#index"
733735
get "/search/facets" => "search_facets#index"
734736
get "/testimonials" => "testimonials#index"

swagger/v1/api_public_swagger.yaml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,11 @@ paths:
918918
required: false
919919
schema:
920920
type: string
921+
- name: palette_id
922+
in: query
923+
required: false
924+
schema:
925+
type: string
921926
responses:
922927
'200':
923928
description: theme found
@@ -974,6 +979,103 @@ paths:
974979
custom_css:
975980
type: string
976981
nullable: true
982+
"/api_public/v1/themes/{theme_name}/palettes":
983+
get:
984+
summary: Lists available palettes for a theme
985+
tags:
986+
- Theme Palettes
987+
parameters:
988+
- name: theme_name
989+
in: path
990+
required: true
991+
schema:
992+
type: string
993+
responses:
994+
'200':
995+
description: palette list found
996+
content:
997+
application/json:
998+
schema:
999+
type: object
1000+
properties:
1001+
theme:
1002+
type: string
1003+
palettes:
1004+
type: array
1005+
items:
1006+
type: object
1007+
properties:
1008+
id:
1009+
type: string
1010+
name:
1011+
type: string
1012+
description:
1013+
type: string
1014+
nullable: true
1015+
preview_colors:
1016+
type: array
1017+
items:
1018+
type: string
1019+
is_default:
1020+
type: boolean
1021+
supports_dark_mode:
1022+
type: boolean
1023+
has_explicit_dark_mode:
1024+
type: boolean
1025+
"/api_public/v1/themes/{theme_name}/palettes/{palette_id}":
1026+
get:
1027+
summary: Retrieves a single palette for a theme
1028+
tags:
1029+
- Theme Palettes
1030+
parameters:
1031+
- name: theme_name
1032+
in: path
1033+
required: true
1034+
schema:
1035+
type: string
1036+
- name: palette_id
1037+
in: path
1038+
required: true
1039+
schema:
1040+
type: string
1041+
responses:
1042+
'200':
1043+
description: palette found
1044+
content:
1045+
application/json:
1046+
schema:
1047+
type: object
1048+
properties:
1049+
theme:
1050+
type: string
1051+
palette:
1052+
type: object
1053+
properties:
1054+
id:
1055+
type: string
1056+
name:
1057+
type: string
1058+
description:
1059+
type: string
1060+
nullable: true
1061+
preview_colors:
1062+
type: array
1063+
items:
1064+
type: string
1065+
is_default:
1066+
type: boolean
1067+
supports_dark_mode:
1068+
type: boolean
1069+
colors:
1070+
type: object
1071+
additionalProperties:
1072+
type: string
1073+
modes:
1074+
type: object
1075+
additionalProperties:
1076+
type: object
1077+
css_variables:
1078+
type: string
9771079
"/api_public/v1/search/config":
9781080
get:
9791081
summary: Retrieves search configuration

0 commit comments

Comments
 (0)