Add json template to Pages (#8357)

* Add json template to pages

* Add jsonb field, tweak form
This commit is contained in:
Josh Puetz 2020-06-10 09:42:15 -05:00 committed by GitHub
parent fb19703dba
commit d33322f8e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 83 additions and 15 deletions

View file

@ -34,7 +34,7 @@ class Internal::PagesController < Internal::ApplicationController
private
def page_params
allowed_params = %i[title slug body_markdown body_html description template is_top_level_path social_image]
allowed_params = %i[title slug body_markdown body_html body_json description template is_top_level_path social_image]
params.require(:page).permit(allowed_params)
end
end

View file

@ -7,6 +7,7 @@ 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.processed_html if @page.template == "json"
end
def about

View file

@ -157,7 +157,12 @@ class StoriesController < ApplicationController
def handle_page_display
@story_show = true
set_surrogate_key_header "show-page-#{params[:username]}"
render template: "pages/show"
if @page.template == "json"
render json: @page.processed_html
else
render template: "pages/show"
end
end
def handle_base_index

View file

@ -1,5 +1,5 @@
class Page < ApplicationRecord
TEMPLATE_OPTIONS = %w[contained full_within_layout].freeze
TEMPLATE_OPTIONS = %w[contained full_within_layout json].freeze
validates :title, presence: true
validates :description, presence: true
@ -38,7 +38,7 @@ class Page < ApplicationRecord
end
def body_present
errors.add(:body_markdown, "must exist if body_html doesn't exist.") if body_markdown.blank? && body_html.blank?
errors.add(:body_markdown, "must exist if body_html or body_json doesn't exist.") if body_markdown.blank? && body_html.blank? && body_json.blank?
end
def unique_slug_including_users_and_orgs

View file

@ -10,16 +10,25 @@
<%= form.text_field :slug, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :description %>
<%= form.text_field :description, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :template %>
<%= form.select :template, Page::TEMPLATE_OPTIONS, class: "form-control" %>
<p>(Determines the way page's body will be embedded in the layout)</p>
</div>
<div class="form-group optional html">
<%= form.label :body_markdown %>
<%= form.text_area :body_markdown, class: "form-control" %>
</div>
<div class="form-group">
<div class="form-group optional html">
<%= form.label :body_html %> (Only if not using markdown. HTML is dangerous ⚠️)
<%= form.text_area :body_html, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :description %>
<%= form.text_field :description, class: "form-control" %>
<div class="form-group optional json">
<%= form.label :body_json %> (For use with template type <code>json</code>)
<%= form.text_area :body_json, class: "form-control" %>
</div>
<div class="form-group">
<% if @page.social_image_url %>
@ -28,11 +37,6 @@
<%= form.label :social_image %>
<%= form.file_field :social_image, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :template %>
<%= form.select :template, Page::TEMPLATE_OPTIONS, class: "form-control" %>
<p>(Determines the way page's body will be embedded in the layout)</p>
</div>
<div class="form-group">
<%= form.label :is_top_level_path %>
<%= form.check_box :is_top_level_path %>
@ -60,3 +64,29 @@
<% end %>
</div>
</div>
<script>
function showBodyFields() {
// hide all optional elements
$('.optional').css('display','none');
$("select option:selected").each(function () {
if($(this).val() == "json") {
$('.json').css('display','block');
} else {
$('.html').css('display','block');
}
});
};
window.addEventListener('load', function() {
document.getElementById("page_template").onchange = function() {
showBodyFields();
};
showBodyFields();
});
</script>

View file

@ -0,0 +1,5 @@
class AddBodyJsonToPage < ActiveRecord::Migration[6.0]
def change
add_column :pages, :body_json, :jsonb
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_06_08_175130) do
ActiveRecord::Schema.define(version: 2020_06_09_191943) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -797,6 +797,7 @@ ActiveRecord::Schema.define(version: 2020_06_08_175130) do
create_table "pages", force: :cascade do |t|
t.text "body_html"
t.jsonb "body_json"
t.text "body_markdown"
t.datetime "created_at", null: false
t.string "description"

View file

@ -2,10 +2,11 @@ require "rails_helper"
RSpec.describe Page, type: :model do
describe "#validations" do
it "requires either body_markdown or body_html" do
it "requires either body_markdown, body_html, or body_json" do
page = build(:page)
page.body_html = nil
page.body_markdown = nil
page.body_json = nil
expect(page).not_to be_valid
end

View file

@ -16,6 +16,31 @@ RSpec.describe "Pages", type: :request do
expect(response.body).not_to include("/page/#{page.slug}")
expect(response.body).to include("stories-show")
end
context "when json template" do
let_it_be(:json_text) { "{\"foo\": \"bar\"}" }
let_it_be(:page) { create(:page, title: "sample_data", template: "json", body_html: json_text, body_markdown: nil) }
before do
page.save! # Trigger processing of page.body_html
end
it "returns json data " do
get "/page/#{page.slug}"
expect(response.content_type).to eq("application/json")
expect(response.body).to include(json_text)
end
it "returns json data for top level template" do
page.is_top_level_path = true
page.save!
get "/#{page.slug}"
expect(response.content_type).to eq("application/json")
expect(response.body).to include(json_text)
end
end
end
describe "GET /about" do