Skip to content

CM-420 add GovspeakEditor to govspeak-enabled textareas#19

Merged
edavey merged 7 commits into
mainfrom
cm-420-migrate-govspeak-textarea-preview
Sep 3, 2025
Merged

CM-420 add GovspeakEditor to govspeak-enabled textareas#19
edavey merged 7 commits into
mainfrom
cm-420-migrate-govspeak-textarea-preview

Conversation

@edavey
Copy link
Copy Markdown
Collaborator

@edavey edavey commented Sep 2, 2025

Add GovspeakEditor to govspeak-enabled textareas

See Jira CM-420

In this PR we:

  • copy over a simplified version of the mechanism in use on Whitehall for toggling between "Edit" and "Preview" modes on textareas. For now we omit the handling of attachments and images which Whitehall's GovspeakHelper supports. Our content block textareas are much smaller and simpler than the document-scale textareas available in Whitehall
  • remove an unused Whitehall::GovspeakRenderer helper class which was brought over from Whitehall but is not used

Notes on use of Govspeak

1) GovspeakEditor: when editing content (implemented in this PR)

When composing or editing a govspeak-enabled <textarea> we offer users the facility to toggle between "Preview" and "Edit" modes.

When choosing to "Preview" the content of the textarea, we use Ajax to send a POST request to the /admin/preview endpoint. The Admin::PreviewController uses the GovspeakPreviewHelper which ultimately calls #to_haml on a new Govspeak::Document, defined in the govspeak gem, a dependency of the content_block_tools gem.

2) render_govspeak: when displaying saved content

When displaying govspeak-enabled fields which have been saved, on workflow pages such as:

  • editions/1/workflow/group_contact_methods#telephones or
  • editions/1/workflow/review

the EmbeddedObjects::SummaryCard::NestedItemComponent uses the ContentBlockManager::ContentBlock::GovspeakHelper and calls out to render_govspeak in the content_block_tools gem:

module ContentBlockTools
  module Govspeak
    def render_govspeak(body, root_class: nil)
      html = ::Govspeak::Document.new(body).to_html
      Nokogiri::HTML.fragment(html).tap { |fragment|
        fragment.children[0].add_class(root_class) if root_class
      }.to_s.html_safe
    end
  end
end

3) DefaultBlockComponent: rendering entire block

Once a content block is published and can be viewed on the "show" block page: e.g. /content-block/1, we use the DefaultBlockComponent which renders the block using the content_block_tools gem:

ContentBlockTools::ContentBlock.new(
  document_type: "content_block_#{block_type}",
  content_id: document.content_id,
  title:,
  details:,
  embed_code:,
).render

When rendering the ContactComponent, for example, the content_block_tools gem uses ContentBlockTools::Govspeak::render_govspeak (see [2]) on the govspeak-enabled fields. See the telephone_component.html.erb:

<% if show_video_relay_service? %>
  <%= render_govspeak(video_relay_service_content) %>
<% end %>

<% if show_bsl_guidance? %>
  <%= render_govspeak(bsl_guidance[:value], root_class: "content-block__body") %>
<% end %>

<% if show_opening_hours? %>
  <%= render_govspeak(opening_hours[:opening_hours], root_class: "content-block__body") %>
<% end %>

Notes

  • Currently the only fields which can be govspeak enabled are on embedded objects (aka "nested objects", "nested items"). It will take a bit of work to make GovspeakEnabledTextareaComponent general-purpose, as currently govspeak-enabled? is defined only on EmbeddedSchema.

  • We have two similarly named helpers which ought to be combined:

    1. GovspeakPreviewHelper used by GovspeakEditor
    2. GovspeakHelper used by NestedItemComponent
  • We also had (copied over from Whitehall but now deleted) a Whitehall::GovspeakRenderer which inherits from ActionController::Renderer and provides the following helpers methods:

    • govspeak_edition_to_html
    • govspeak_to_html
    • govspeak_with_attachments_to_html
    • govspeak_html_attachment_to_html
    • block_attachments

@edavey edavey force-pushed the cm-420-migrate-govspeak-textarea-preview branch 4 times, most recently from 7b5c854 to 16b7868 Compare September 2, 2025 15:09
@edavey edavey changed the title CM-420 migrate govspeak textarea preview CM-420 add GovspeakEditor to govspeak-enabled textareas Sep 3, 2025
@edavey edavey requested a review from pezholio September 3, 2025 07:01
@edavey edavey marked this pull request as ready for review September 3, 2025 07:01
Comment thread app/assets/javascripts/components/govspeak-editor.js Outdated
locale: options[:locale],
).to_html

"<div class=\"govspeak\">#{html}</div>".html_safe
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to use the content_tag helper here

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but for now I'm just lifting and shifting selected code from Whitehall, so I'd prefer to do refactoring later to avoid any unintended side-effects.

Comment thread test/test_helper.rb Outdated
@edavey edavey force-pushed the cm-420-migrate-govspeak-textarea-preview branch 2 times, most recently from 6d8f956 to 538ace6 Compare September 3, 2025 12:48
@edavey
Copy link
Copy Markdown
Collaborator Author

edavey commented Sep 3, 2025

@pezholio this is ready for another look now

This was brought over from Whitehall but is not used or
currently needed. We remove it to avoid confusion.

This is described as a:

> Helper class to render govspeak outside of the view contexts.
Copy link
Copy Markdown
Contributor

@pezholio pezholio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@edavey edavey force-pushed the cm-420-migrate-govspeak-textarea-preview branch from 538ace6 to 775e11c Compare September 3, 2025 14:53
@edavey edavey merged commit 085e6d0 into main Sep 3, 2025
22 checks passed
@edavey edavey deleted the cm-420-migrate-govspeak-textarea-preview branch September 3, 2025 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants