Skip to content

Commit

Permalink
Merge pull request #9640 from alphagov/content-modelling/659-preview-…
Browse files Browse the repository at this point in the history
…with-embedded

Content modelling/659 Preview Host Documents via iFrame
  • Loading branch information
Harriethw authored Nov 26, 2024
2 parents dc7b944 + 3f460cc commit 216bbbf
Show file tree
Hide file tree
Showing 18 changed files with 288 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
class ContentBlockManager::ContentBlock::Document::Show::HostEditionsTableComponent < ViewComponent::Base
TABLE_ID = "host_editions"

def initialize(caption:, host_content_items:, is_preview: false, current_page: nil, order: nil)
def initialize(caption:, host_content_items:, content_block_edition:, is_preview: false, current_page: nil, order: nil)
@caption = caption
@host_content_items = host_content_items
@is_preview = is_preview
@current_page = current_page.presence || 1
@order = order.presence || ContentBlockManager::GetHostContentItems::DEFAULT_ORDER
@content_block_edition = content_block_edition
end

def current_page
Expand All @@ -25,7 +26,7 @@ def base_pagination_path

private

attr_reader :caption, :host_content_items, :order
attr_reader :caption, :host_content_items, :order, :content_block_edition

def rows
return [] unless host_content_items
Expand Down Expand Up @@ -81,7 +82,7 @@ def users

def frontend_path(content_item)
if @is_preview
Plek.external_url_for("draft-origin") + content_item.base_path
helpers.content_block_manager.content_block_manager_content_block_host_content_preview_path(id: content_block_edition.id, host_content_id: content_item.host_content_id)
else
Plek.website_root + content_item.base_path
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class ContentBlockManager::ContentBlock::Editions::HostContentController < ContentBlockManager::BaseController
def preview
host_content_id = params[:host_content_id]
content_block_edition = ContentBlockManager::ContentBlock::Edition.find(params[:id])
@preview_content = ContentBlockManager::GetPreviewContent.for_content_id(content_id: host_content_id, content_block_edition:)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class HostContentItem < Data.define(
:last_edited_at,
:unique_pageviews,
:instances,
:host_content_id,
)

def last_edited_at
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module ContentBlockManager
class PreviewContent < Data.define(:title, :html)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def items
last_edited_at: item["last_edited_at"],
unique_pageviews: item["unique_pageviews"],
instances: item["instances"],
host_content_id: item["host_content_id"],
)
end

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
require "net/http"
require "json"
require "uri"

module ContentBlockManager
class GetPreviewContent
def self.for_content_id(content_id:, content_block_edition:)
new(content_id:, content_block_edition:).for_content_id
end

def for_content_id
ContentBlockManager::PreviewContent.new(title: content_item["title"], html:)
end

private

def initialize(content_id:, content_block_edition:)
@content_id = content_id
@content_block_edition = content_block_edition
end

def html
@html ||= preview_html
end

def content_item
@content_item ||= begin
response = Services.publishing_api.get_content(@content_id)
response.parsed_content
end
end

def frontend_base_path
Rails.env.development? ? Plek.external_url_for("government-frontend") : Plek.website_root
end

def frontend_path
frontend_base_path + content_item["base_path"]
end

def preview_html
uri = URI(frontend_path)
nokogiri_html = html_snapshot_from_frontend(uri)
replace_existing_content_blocks(nokogiri_html)
end

def replace_existing_content_blocks(nokogiri_html)
replace_blocks(nokogiri_html)
style_blocks(nokogiri_html)
nokogiri_html
end

def replace_blocks(nokogiri_html)
@preview_content_block_render ||= @content_block_edition.render
content_block_spans(nokogiri_html).each do |span|
span.replace @preview_content_block_render
end
end

BLOCK_STYLE = "background-color: yellow;".freeze

def style_blocks(nokogiri_html)
content_block_spans(nokogiri_html).each do |span|
span["style"] = BLOCK_STYLE
end
end

def content_block_spans(nokogiri_html)
nokogiri_html.css("span[data-content-id=\"#{@content_block_edition.document.content_id}\"]")
end

ERROR_HTML = "<html><body><p>Preview not found</p></body></html>".freeze

def html_snapshot_from_frontend(uri)
begin
raw_html = Net::HTTP.get(uri)
rescue StandardError
raw_html = ERROR_HTML
end
Nokogiri::HTML.parse(raw_html)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
host_content_items: @host_content_items,
current_page: @page,
order: @order,
content_block_edition: @content_block_document.latest_edition,
),
) %>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<% content_for :page_title, "Preview content block in host document" %>
<% content_for :context, "Preview content block" %>
<% content_for :title, @preview_content.title %>
<% content_for :title_margin_bottom, 0 %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds govuk-body govuk-!-margin-bottom-0">
<p><strong>Document title: </strong><%= @preview_content.title %></p>
</div>
</div>
<hr class="govuk-section-break govuk-!-margin-bottom-8 govuk-section-break--visible">
<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
<iframe id="preview" style="width:100%;height:80vh;" srcdoc="<%= @preview_content.html %>"></iframe>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
host_content_items: @host_content_items,
current_page: @page,
order: @order,
content_block_edition: @content_block_edition,
),
) %>
</div>
Expand Down
3 changes: 3 additions & 0 deletions lib/engines/content_block_manager/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
resources :editions, only: %i[new create destroy], path_names: { new: ":block_type/new" } do
member do
resources :workflow, only: %i[show update], controller: "editions/workflow", param: :step
resources :host_content, only: %i[preview], controller: "editions/host_content", param: :id do
get :preview, to: "editions/host_content#preview"
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,10 @@ Feature: Edit a content object
And I visit the Content Block Manager home page
Then I should still see the live edition on the homepage

@javascript
Scenario: GDS editor can preview a host document
When I revisit the edit page
And I fill out the form
Then I am shown where the changes will take place
And the host documents link to the draft content store
When I click on the first host document
Then The preview page opens in a new tab
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def should_show_edit_form_for_email_address_content_block(document_title, email_
{
"title" => "Content #{i}",
"document_type" => "document",
"base_path" => "/",
"base_path" => "/host-content-path-#{i}",
"content_id" => SecureRandom.uuid,
"last_edited_by_editor_id" => SecureRandom.uuid,
"last_edited_at" => 2.days.ago.to_s,
Expand Down Expand Up @@ -486,7 +486,40 @@ def should_show_edit_form_for_email_address_content_block(document_title, email_
end

When("I click on the first host document") do
click_on @dependent_content.first["title"]
@current_host_document = @dependent_content.first
stub_request(
:get,
"#{Plek.find('publishing-api')}/v2/content/#{@current_host_document['host_content_id']}",
).to_return(
status: 200,
body: {
details: {
body: "<p>title</p>",
},
title: @current_host_document["title"],
document_type: "news_story",
base_path: @current_host_document["base_path"],
publishing_app: "test",
}.to_json,
)

stub_request(
:get,
Plek.website_root + @current_host_document["base_path"],
).to_return(
status: 200,
body: "<h1>#{@current_host_document['title']}</h1><p>iframe preview</p>",
)

click_on @current_host_document["title"]
end

Then("The preview page opens in a new tab") do
page.switch_to_window(page.windows.last)
assert_text "Preview content block"
within_frame "preview" do
assert_text @current_host_document["title"]
end
end

When(/^I save and continue$/) do
Expand Down
Loading

0 comments on commit 216bbbf

Please sign in to comment.