Add CSS as pages template option (#20512)

* add css as pages option

* don't forget schema

* fix test

* add api support
This commit is contained in:
Philip How 2024-01-12 15:35:38 +00:00 committed by GitHub
parent 1c25171cc6
commit 33fd9836be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 55 additions and 7 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -47,6 +47,13 @@
<p class="crayons-field__description">For use with template type <code>json</code></p>
<% end %>
<%= form.text_area :body_json, rows: 10, class: "crayons-textfield" %>
</div>
<div class="crayons-field optional css">
<%= form.label :body_css, class: "crayons-field__label" do %>
Body CSS
<p class="crayons-field__description">For use with template type <code>css</code></p>
<% end %>
<%= form.text_area :body_css, rows: 10, class: "crayons-textfield" %>
</div>
<div class="crayons-field">
<% 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');
}

View file

@ -0,0 +1,5 @@
class AddCssToPages < ActiveRecord::Migration[7.0]
def change
add_column :pages, :body_css, :text
end
end

View file

@ -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"

View file

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

View file

@ -71,6 +71,7 @@ RSpec.describe "Api::V1::Pages" do
attributes_for(:page)
end
let(:body_html) { "<div>hi, folks</div>" }
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)