From 33fd9836beb31c725bf1a16928ab8cf2ed8b4692 Mon Sep 17 00:00:00 2001 From: Philip How Date: Fri, 12 Jan 2024 15:35:38 +0000 Subject: [PATCH] Add CSS as pages template option (#20512) * add css as pages option * don't forget schema * fix test * add api support --- app/controllers/admin/pages_controller.rb | 2 +- app/controllers/api/v1/pages_controller.rb | 2 +- app/controllers/pages_controller.rb | 7 ++++- app/models/page.rb | 4 +-- app/views/admin/pages/_form.html.erb | 9 +++++++ db/migrate/20240111144401_add_css_to_pages.rb | 5 ++++ db/schema.rb | 3 ++- spec/models/page_spec.rb | 3 ++- spec/requests/api/v1/pages_spec.rb | 27 +++++++++++++++++++ 9 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20240111144401_add_css_to_pages.rb diff --git a/app/controllers/admin/pages_controller.rb b/app/controllers/admin/pages_controller.rb index f02a45bff..8f6d9f824 100644 --- a/app/controllers/admin/pages_controller.rb +++ b/app/controllers/admin/pages_controller.rb @@ -3,7 +3,7 @@ module Admin layout "admin" PAGE_ALLOWED_PARAMS = %i[ - title slug body_markdown body_html body_json description template + title slug body_markdown body_html body_json body_css description template is_top_level_path social_image landing_page ].freeze diff --git a/app/controllers/api/v1/pages_controller.rb b/app/controllers/api/v1/pages_controller.rb index 6b523ab46..3d4aa4091 100644 --- a/app/controllers/api/v1/pages_controller.rb +++ b/app/controllers/api/v1/pages_controller.rb @@ -40,7 +40,7 @@ module Api def permitted_params params.permit(*%i[title slug description is_top_level_path - body_json body_markdown body_html social_image template]) + body_json body_markdown body_html body_css social_image template]) end end end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 27d09a24b..3c627b368 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -7,7 +7,12 @@ class PagesController < ApplicationController not_found unless FeatureFlag.accessible?(@page.feature_flag_name, current_user) set_surrogate_key_header "show-page-#{params[:slug]}" - render json: @page.body_json if @page.template == "json" + case @page.template + when "json" + render json: @page.body_json + when "css" + render plain: @page.body_css, content_type: "text/css" + end end def about diff --git a/app/models/page.rb b/app/models/page.rb index 5b47311ea..df31cafcd 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -1,6 +1,6 @@ class Page < ApplicationRecord extend UniqueAcrossModels - TEMPLATE_OPTIONS = %w[contained full_within_layout nav_bar_included json].freeze + TEMPLATE_OPTIONS = %w[contained full_within_layout nav_bar_included json css].freeze TERMS_SLUG = "terms".freeze CODE_OF_CONDUCT_SLUG = "code-of-conduct".freeze @@ -80,7 +80,7 @@ class Page < ApplicationRecord end def body_present - return unless body_markdown.blank? && body_html.blank? && body_json.blank? + return unless body_markdown.blank? && body_html.blank? && body_json.blank? && body_css.blank? errors.add(:body_markdown, I18n.t("models.page.body_must_exist")) end diff --git a/app/views/admin/pages/_form.html.erb b/app/views/admin/pages/_form.html.erb index bdaf3bb62..f08ade782 100644 --- a/app/views/admin/pages/_form.html.erb +++ b/app/views/admin/pages/_form.html.erb @@ -47,6 +47,13 @@

For use with template type json

<% end %> <%= form.text_area :body_json, rows: 10, class: "crayons-textfield" %> + +
+ <%= form.label :body_css, class: "crayons-field__label" do %> + Body CSS +

For use with template type css

+ <% end %> + <%= form.text_area :body_css, rows: 10, class: "crayons-textfield" %>
<% if @page.social_image_url %> @@ -128,6 +135,8 @@ function showBodyFields() { document.querySelectorAll("select").forEach(el => { if (el.options[el.selectedIndex].value == "json") { document.querySelectorAll('.json').forEach(el => el.style.display = 'block'); + } else if (el.options[el.selectedIndex].value == "css") { + document.querySelectorAll('.css').forEach(el => el.style.display = 'block'); } else { document.querySelectorAll('.html').forEach(el => el.style.display = 'block'); } diff --git a/db/migrate/20240111144401_add_css_to_pages.rb b/db/migrate/20240111144401_add_css_to_pages.rb new file mode 100644 index 000000000..34e376d85 --- /dev/null +++ b/db/migrate/20240111144401_add_css_to_pages.rb @@ -0,0 +1,5 @@ +class AddCssToPages < ActiveRecord::Migration[7.0] + def change + add_column :pages, :body_css, :text + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index 5308ba191..8f9393d8f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_01_03_223627) do +ActiveRecord::Schema[7.0].define(version: 2024_01_11_144401) do # These are extensions that must be enabled in order to support this database enable_extension "citext" enable_extension "ltree" @@ -783,6 +783,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_03_223627) do end create_table "pages", force: :cascade do |t| + t.text "body_css" t.text "body_html" t.jsonb "body_json" t.text "body_markdown" diff --git a/spec/models/page_spec.rb b/spec/models/page_spec.rb index d2c2453dd..3d105345b 100644 --- a/spec/models/page_spec.rb +++ b/spec/models/page_spec.rb @@ -32,11 +32,12 @@ RSpec.describe Page do end describe "#validations" do - it "requires either body_markdown, body_html, or body_json" do + it "requires either body_markdown, body_html, body_json or body_css" do page = build(:page) page.body_html = nil page.body_markdown = nil page.body_json = nil + page.body_css = nil expect(page).not_to be_valid end diff --git a/spec/requests/api/v1/pages_spec.rb b/spec/requests/api/v1/pages_spec.rb index 93d3e3388..0bc84ea1b 100644 --- a/spec/requests/api/v1/pages_spec.rb +++ b/spec/requests/api/v1/pages_spec.rb @@ -71,6 +71,7 @@ RSpec.describe "Api::V1::Pages" do attributes_for(:page) end let(:body_html) { "
hi, folks
" } + let(:body_css) { "h1 {font-size: 120px}" } it "can create a new page via post" do post api_pages_path, params: post_params.to_json, headers: auth_header @@ -121,6 +122,32 @@ RSpec.describe "Api::V1::Pages" do expect(page.reload.processed_html).to include("other") end + it "creates a page with body_css" do + post_params[:template] = "css" + post_params[:body_css] = body_css + post_params[:body_markdown] = "" + post api_pages_path, params: post_params.to_json, headers: auth_header + page = Page.find_by(title: post_params[:title]) + expect(page.body_css).to eq(body_css) + end + + it "doesn't create a page when no html or md or css are passed" do + post_params[:template] = "css" + post_params[:body_html] = nil + post_params[:body_markdown] = nil + post_params[:body_css] = nil + post api_pages_path, params: post_params.to_json, headers: auth_header + page = Page.find_by(title: post_params[:title]) + expect(page).to be_nil + end + + it "updates an existing page via put with body_css" do + post_params = page.attributes.merge(body_css: body_css, body_markdown: nil, template: "css") + put api_page_path(page.id), params: post_params.to_json, headers: auth_header + expect(response).to have_http_status(:success) + expect(page.reload.body_css).to eq(body_css) + end + it "can destroy an existing page via delete" do delete api_page_path(page.id), headers: auth_header expect(response).to have_http_status(:success)