|
| 1 | +# Use of Govspeak |
| 2 | + |
| 3 | +September 3, 2025. |
| 4 | + |
| 5 | +Govspeak is the GOV.UK flavour of markdown which is offered to content creators |
| 6 | +to format their work. |
| 7 | + |
| 8 | +This is a summary of how, at this point in time, we are converting Govspeak into |
| 9 | +HTML. |
| 10 | + |
| 11 | +## 1) GovspeakEditor: when editing content |
| 12 | + |
| 13 | +When composing or editing a govspeak-enabled `<textarea>` we offer users the |
| 14 | +facility to toggle between "Preview" and "Edit" modes. |
| 15 | + |
| 16 | +When choosing to "Preview" the content of the textarea, we use Ajax to send a |
| 17 | +`POST` request to the `/admin/preview` endpoint. The `Admin::PreviewController` |
| 18 | +uses the `GovspeakPreviewHelper` which ultimately calls `#to_haml` on a new |
| 19 | +`Govspeak::Document`, defined in the `govspeak` gem, a dependency of the |
| 20 | +`content_block_tools` gem. |
| 21 | + |
| 22 | +## 2) render_govspeak: when displaying saved content |
| 23 | + |
| 24 | +When displaying govspeak-enabled fields which have been saved, on workflow pages |
| 25 | +such as: |
| 26 | + |
| 27 | +- `editions/1/workflow/group_contact_methods#telephones` or |
| 28 | +- `editions/1/workflow/review` |
| 29 | + |
| 30 | +The `EmbeddedObjects::SummaryCard::NestedItemComponent` uses the |
| 31 | +`ContentBlockManager::ContentBlock::GovspeakHelper` and calls out to |
| 32 | +`render_govspeak` in the content_block_tools gem: |
| 33 | + |
| 34 | +```rb |
| 35 | +module ContentBlockTools |
| 36 | + module Govspeak |
| 37 | + def render_govspeak(body, root_class: nil) |
| 38 | + html = ::Govspeak::Document.new(body).to_html |
| 39 | + Nokogiri::HTML.fragment(html).tap { |fragment| |
| 40 | + fragment.children[0].add_class(root_class) if root_class |
| 41 | + }.to_s.html_safe |
| 42 | + end |
| 43 | + end |
| 44 | +end |
| 45 | +``` |
| 46 | + |
| 47 | +## 3) DefaultBlockComponent: rendering entire block |
| 48 | + |
| 49 | +Once a content block is published and can be viewed on the "show" block page: |
| 50 | +e.g. `/content-block/1`, we use the `DefaultBlockComponent` which renders the |
| 51 | +block using the `content_block_tools` gem: |
| 52 | + |
| 53 | +```rb |
| 54 | +ContentBlockTools::ContentBlock.new( |
| 55 | + document_type: "content_block_#{block_type}", |
| 56 | + content_id: document.content_id, |
| 57 | + title:, |
| 58 | + details:, |
| 59 | + embed_code:, |
| 60 | +).render |
| 61 | +``` |
| 62 | + |
| 63 | +When rendering the `ContactComponent`, for example, the `content_block_tools` |
| 64 | +gem uses `ContentBlockTools::Govspeak::render_govspeak` (see [2]) on the |
| 65 | +govspeak-enabled fields. See the `telephone_component.html.erb`: |
| 66 | + |
| 67 | +```rb |
| 68 | +<% if show_video_relay_service? %> |
| 69 | + <%= render_govspeak(video_relay_service_content) %> |
| 70 | +<% end %> |
| 71 | +
|
| 72 | +<% if show_bsl_guidance? %> |
| 73 | + <%= render_govspeak(bsl_guidance[:value], root_class: "content-block__body") %> |
| 74 | +<% end %> |
| 75 | + |
| 76 | +<% if show_opening_hours? %> |
| 77 | + <%= render_govspeak(opening_hours[:opening_hours], root_class: "content-block__body") %> |
| 78 | +<% end %> |
| 79 | +``` |
| 80 | +
|
| 81 | +## Notes |
| 82 | +
|
| 83 | +- Currently the only fields which can be govspeak-enabled are on embedded objects |
| 84 | +(aka "nested objects", "nested items"). It will take a bit of work to make |
| 85 | +`GovspeakEnabledTextareaComponent` general-purpose, as currently `govspeak-enabled?` |
| 86 | +is defined only on `EmbeddedSchema`. |
| 87 | +
|
| 88 | +- We have two similarly named helpers which ought to be combined: |
| 89 | +
|
| 90 | + 1. `GovspeakPreviewHelper` used by GovspeakEditor |
| 91 | + 2. `GovspeakHelper` used by `NestedItemComponent` |
| 92 | +
|
| 93 | +- We also had (copied over from Whitehall but now deleted) a |
| 94 | +`Whitehall::GovspeakRenderer` which inherits from `ActionController::Renderer` |
| 95 | +and provides the following `helpers` methods: |
| 96 | +
|
| 97 | + - `govspeak_edition_to_html` |
| 98 | + - `govspeak_to_html` |
| 99 | + - `govspeak_with_attachments_to_html` |
| 100 | + - `govspeak_html_attachment_to_html` |
| 101 | + - `block_attachments` |
0 commit comments