-
Notifications
You must be signed in to change notification settings - Fork 120
Support HTML content within templates #4502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
2efbc0e
to
c2856c2
Compare
9470d4a
to
b21e700
Compare
b21e700
to
389e14d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job Sean, looks like this opens up lots of opportunities to give Smart Answers a bit more polish and be more flexible for future endeavours.
A few things come to mind:
- We've got a whole ton of files with govspeak.erb extensions that can now be mixed media, shall we change all of those to .erb
- There is this somewhat quirky feature in Smart Answers where it takes the text of answers and puts them into the content item as hidden search terms (For example, the details->hidden_search_terms array in: https://www.gov.uk/api/content/business-coronavirus-support-finder) I'm not sure how that works and/or if it uses the text handling
- Another quirky thing we've got is the MarriageAbroadOutcomeFlattener, which I believe Platform Health may use, I don't know if that'll be negatively impacted at all? It's super weird so would be great to remove it
@@ -14,22 +14,22 @@ def initialize(template_directory:, template_name:, locals: {}, helpers: []) | |||
@template_directory = template_directory | |||
@template_name = template_name | |||
@locals = locals | |||
lookup_context = ActionView::LookupContext.new([@template_directory, FlowRegistry.instance.load_path]) | |||
default_view_paths = ActionController::Base.view_paths.paths.map(&:to_s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks familiar 😉 - I do wonder if there's a less cryptic way to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahah yup, definitely pinched that. Had a look and can't see an obvious nicer solution. Essentially what we are trying to do is get the govuk_publishing_components views in the view path (which is system dependent). So could do something like:
lookup_context = ActionView::LookupContext.new([
@template_directory,
FlowRegistry.instance.load_path,
File.expand_path("app/views", GovukPublishingComponents::Config.gem_directory),
])
But felt like this is making assumptions about where the views live inside GovukPublishingComponents
@@ -0,0 +1,64 @@ | |||
module SmartAnswer | |||
module Helpers::FormatCaptureHelper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a slightly strange namespace for this to be - as this is a component of the ErbRenderer it might make sense under that. Under helpers gives me the impression this is shared around whereas this is only used in one context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah good point! I'll try and re-organise this better - I think I was just trying to the code in to another file, because the erb_renderer.rb was getting super long.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved them under the ErbRenderer namespace.
text: [/^title$/, /^meta_description$/, /^hint$/, /^label$/, /^suffix_label$/, /^error_*./], | ||
}.freeze | ||
|
||
def content_for(name, content = nil, options = {}, &block) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wondered whether it'd be good to rename this so that it didn't clobber the existing content_for function that ActiveView provides. Maybe it's too much of a pain in this repo at this point but it feels like we're breaking the L in SOLID that the subclassing of this function stops the original use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup agree, I was trying limit breaking changes how existing templates are currently written, but probably safer to give it a new name and not try to deal with Rails internals.
|
||
should "render govspeak by default" do | ||
assert_captured_content("content", nil, "<g><p>content</p></g>") | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to also make clear that it's wrapped in govspeak component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully the larger refactor of the tests makes this clear now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I've been beaten to the review here! I do like the end result - it's neat ✏️. I'm content with the overall approach, and we should just address a few things before this goes in.
6018a6d
to
d063a43
Compare
d063a43
to
a3608b2
Compare
@kevindew @benthorner Thanks for the review and all the comments! Appreciate this becoming quite large and there's a lot going on - if its helpful, I can try split off smaller PRs? (The commits may be easier to follow)
Yup - happy for me to change that in a separate PR?
We should be good! The hidden_search_terms array is generated here - looks like it strips out HTML and is getting strings from the Outcome and Question Presenters, which were always rendered Govspeak anyway.
Should be good too! - it just generates partials from a yaml file, but the views that use them e.g here them has been updated. The templates from which the partials are generated in the MarriageAbroadOutcomeFlattener aren't effected. |
a3608b2
to
a063b42
Compare
a063b42
to
9c16e5a
Compare
9c16e5a
to
46ae163
Compare
46ae163
to
7c19e3a
Compare
7c19e3a
to
d63b666
Compare
This feature was used for debugging by allowing a user to append .txt to a url to show the govspeak unrendered. This adds complexity to the view rendering logic with little value as a user can reference the source code instead.
This parameter provided the option to retrieve content without processing it as govspeak i.e `html: false` prevents the block being processed as govspeak and returns plain text. This is no longer needed as it was used for a debugging feature to user unprocessed govspeak, which was removed in earlier commits.
This prefix's error messages with `error_` so they conform to conventions outlined in the documentation.
The FormatCaptureHelper was added to render content_for blocks within smart answer templates. Previously it was not possible to specify the content type for particular sections within the template, as they were all post-processed in the same way. e.g. content for the body was always passed through the Govspeak processor before being rendered in the main views (result, question, start). Therefore there was no way to specify a content format within the node template. e.g. html content for the body, not processed by govspeak. This helper enables the option to specify a content format with the content_for function within the node template. To enable this we are also expanding the view paths of ErbRenderer to include those from Rail's ActionController::Base. This is because we need access GovukPublishingComponents to fully render govspeak.
As rendering of the content_for block is done at view render time. There is no need to have individual methods to access types of content from the ErbRenderer. Access can be simplified to simply delegating to the ActiveView::Base#content_for method.
Govspeak is rendered and wrapped with the govspeak component when the content_for is called in the template. Therefore there are redundant wrapping of govspeak within the main views (i.e. results, questions and landing views)
This adds the :html format for content_for block. It should render the block as is.
For consistency wih FormatCaptureHelper, this code was moved to a seperated file under the helpers folder.
The FormatCaptureHelper and QuestionOptionHelper were under the general helper module namespace. To make it more clear their purpose, they have been moved under the ErbRenderer namespace.
d63b666
to
d1ec375
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wowsers - this is a huge PR (> 900 files 😵). I've only really given a lot of them a scroll through.
I've put just a minor comment on that can be fixed without a re-review.
I do find myself a bit baffled by the render_content_for method, the naming seems a bit confusing outside of govspeak. Though I understand this naming has been what has dragged on this PR and I don't want to block your team over it. What's next for the naming discussion once this is merged?
Previously this method was intented to override the `content_for` within ActiveView::Helpers:CaptureHelper. This changed the expected behaviour of content_for within template and could lead to confusion. It also put dependency on undocumented behaviour of the content_for within Rails, which could be fragile and confusing to support in the future. This change requires an update to all templates to use the renamed method.
As this option is only used by render_content_for, it is removed before being passed on to content_for to prevent any potential side effects.
No longer used.
Previously render_content_for marked strings of text format as html_safe. However this lead to the possibility of character's not being properly escaped. e.g. you shouldn't be able to write HTML in the text field.
d1ec375
to
8849dfc
Compare
Thanks @kevindew!
Yeah sorry, most of its the renaming from
Yup, so I've opened issue #4510 to continue discussion. I was initial hesitant to merge this, but think it's fine given the previous behaviour had the same issues (i.e. |
Great stuff - looks like this is good to merge. |
Here we aim to add support for more content types within named
render_content_for
blocks. Previously it wasn't possible to specify the content type within the template. e.g content_for :body is always rendered as Govspeak.This PR adds the format option to render_content_for method within templates.
This new option supports
:govspeak
,:text
and:html
. Named blocks (e.g.:title
,:body
etc) have individual defaults, which are outlined in the docs. Otherwise all blocks default to:govspeak
.To enable this the following changes have been made:
.txt
on URLs. This was a debugging feature, however cannot be supported as content is pre-processed into the required format before being added to the main view. It also seemed to add unnecessary complexity when the source code is available to read.error_
prefix for error message names. This is to allow a default format of :text to apply to that error message content.