-
Notifications
You must be signed in to change notification settings - Fork 21
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
New link helpers #419
New link helpers #419
Conversation
✅ Deploy Preview for govuk-components ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
4ea9703
to
b0f9d4e
Compare
@peteryates I tried to look at this diff, but there’s a lot of changes so it's quite hard to follow (at least for me). Would you mind summarising the main changes to the helpers that this PR proposes? Maybe a before & after would help? |
@frankieroberto yeah, good call. I added a replacement helper that has the same methods in it and I think the fact I changed the order has made the diff more difficult to digest than it should be. I'll see if I can improve it and write a full summary. Essentially though the old helpers follow a format like this: def govuk_link_to(name = nil, options = nil, extra_options = {}, &block)
extra_options = options if block_given?
html_options = build_html_options(extra_options)
if block_given?
link_to(name, html_options, &block)
else
link_to(name, options, html_options)
end
end As you can see here, It's very brittle and caught me out when I tried to add the This change switches everything over to keyword arguments, allowing the code to be much simpler. Most projects shouldn't notice any change. It might bite some that are using the old style Rails format, but the Rails docs have advised against using them for years and I barely see any in the wild so I don't image it's widespread. They will be able to continue using the old ones for the time being. |
app/helpers/govuk_link_helper.rb
Outdated
fail(ArgumentError, "invalid styles #{invalid_styles.to_sentence}. Valid styles are #{LINK_STYLES.keys.to_sentence}") | ||
def govuk_link_classes(inverse: false, muted: false, no_underline: false, no_visited_state: false, text_colour: false) | ||
if [text_colour, inverse, muted].count(true) > 1 | ||
fail("links can be either text_colour, inverse or muted - not combinations of the three") |
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 could definitely be worded better. Is it even needed at all? 🤔
@peteryates ah ok, so it’d still be the case that the first argument would be the link text and the second one the path/url, but after that you’d use keyword arguments for any extra attributes or options? |
Yeah - exactly that. Then any GOV.UK specific ones will be picked up and used to assign the relevant classes/attributes and any extra ones ( Essentially it's switching away from having to extract the GOV.UK specific stuff from a generic hash of arguments. |
This is likely to be one of the features of v5.0.0 which will be released following govuk-frontend 5. |
640125c
to
4c0eaca
Compare
✅ Deploy Preview for govuk-components ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
@frankieroberto - in terms of reviewing this, the diff will be confusing because the change moves the old link helpers to a different file and adds new implementations in their place. The method names are the same so if people want to use the originals they can manually include the module, but the new ones will be default. The code is much cleaner in the new ones so they should be easy to review on their own. In making this change we lose the old Rails way of creating links, but that's actively discouraged by the Rails docs and you don't really see it any more (although we do have some in ECF!) |
@peteryates thanks, I'll try to review! Would you mind updating the PR description to show what the old and new link syntax looks like? That might make it a bit clearer. |
Have done, and here's a comparison of old vs new: # old
link_to("Show profile", controller: "profiles", action: "show", id: @profile)
# new (restful)
link_to("Show profile", profile_path(@profile)) |
Thanks! I've not seen anyone use the old style for ages! Presumably both examples should be Will anyone using the old style get an error, or will it just render a link but in an unexpected way? |
I was just showing the Rails defaults when demonstrating the formats, but I've chagnged it to
They'll get an |
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.
Left some comments/suggestions - but feel free to ignore. Looks good!
def govuk_link_classes(*styles, default_class: "#{brand}-link") | ||
if (invalid_styles = (styles - link_styles.keys)) && invalid_styles.any? | ||
fail(ArgumentError, "invalid styles #{invalid_styles.to_sentence}. Valid styles are #{link_styles.keys.to_sentence}") | ||
end | ||
|
||
[default_class] + link_styles.values_at(*styles).compact | ||
end | ||
|
||
def govuk_button_classes(*styles, default_class: "#{brand}-button") | ||
if (invalid_styles = (styles - button_styles.keys)) && invalid_styles.any? | ||
fail(ArgumentError, "invalid styles #{invalid_styles.to_sentence}. Valid styles are #{button_styles.keys.to_sentence}") | ||
end | ||
|
||
[default_class] + button_styles.values_at(*styles).compact | ||
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.
Should these be private methods? Can't think of why you'd use them outside of a link or button helper.
If not, maybe move them below the other methods, and add a brief comment to explain what they do? It threw me a bit seeing these alongside the more obvious helper methods below.
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.
So these are exposed to make it easier for devs to use Rails' other link helpers, like link_to_if
and link_to_unless
, link_to_unless_current
, etc.
extra_options = options if block_given? | ||
html_options = build_html_options(extra_options) | ||
|
||
if block_given? | ||
link_to(name, html_options, &block) | ||
else | ||
link_to(name, options, html_options) | ||
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.
I think you can avoid the if
conditions here and always pass block
on to the rails helpers, as those do their own if block_given?
checks?
extra_options = options if block_given? | |
html_options = build_html_options(extra_options) | |
if block_given? | |
link_to(name, html_options, &block) | |
else | |
link_to(name, options, html_options) | |
end | |
extra_options = options if block_given? | |
html_options = build_html_options(extra_options) || nil | |
link_to(name, options, html_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.
Going to leave these as they're in the legacy implementation which will soon be dropped.
describe "#govuk_link_to" do | ||
let(:link_text) { 'Onwards!' } | ||
let(:link_url) { '/some/link' } | ||
let(:link_params) { { controller: :some_controller, action: :some_action } } |
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.
Confused by this - thought you’d deprecated this method, and now always require a path to be set instead of setting a controller and action?
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 covers the old helpers which are still present (in GovukRailsCompatibileLinkHelper
) for teams working on codebases that won't support the new style.
These are clean implementations of that significantly simplify the codebase and allow us to easily support features of the design system, like opening links in new tabs. The new methods are: * govuk_link_to * govuk_button_to * govuk_button_link_to * govuk_link_classes * govuk_button_classes * govuk_breadcrumb_link_to They drop support for Rails' legacy-style link building where the action, controller and id arguments were passed in. Rails discourages their use in the API docs[0]: > Because it relies on url_for, link_to supports both older-style > controller/action/id arguments and newer RESTful routes. Current Rails > style favors RESTful routes whenever possible, so base your application > on resources and use [0] https://api.rubyonrails.org/v7.0/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
Nanoc's link helpers expect classes to be provided in a string but now we're using arrays internally throughout so it makes sense to use the Rails version.
Now we're using the new link helper we need to use keyword arguments instead of hashes or arrays.
Co-authored-by: Frankie Roberto <frankie@frankieroberto.com>
4c0eaca
to
ceba1d0
Compare
Following the release of [GOV.UK Design System v5.0](https://github.com/alphagov/govuk-design-system/milestone/16), govuk-components v5.0.0 will be released. The headline features are: * support for GOV.UK Design System v5.0 * inclusion of [the task list component](alphagov/govuk-frontend#2261) #425 * all new link helpers #419 * update header to use new SVG which combines the crown and the GOV.UK test #466 Release notes will be drafted in #469.
This PR introduces a new set of link helpers that will
be available as an option but will eventually become defaultbe the default. The legacy 100% Rails-compatible helpers will still be available for the time being by including the helper module as described below.The current helpers are closely tied to Rails' implementation which after 18 years is showing its age. Because it pre-dates keyword arguments and can take many formats of link, the code is complex and difficult to extend.
The new implementation:
govuk_link_to("Show profile", controller: "profiles", action: "show", id: @profile)
format. I haven't seen much evidence of this style in use and Rails' documentation advises against using itMultiple versions of link helpers
For a while there will be two versions of the link helpers:
GovukLinkHelper
GovukRailsCompatibileLinkHelper
I originally planned to make choosing between them a config option but due to the order the gem is required and then the intializers run, it's a pain. Instead, the new ones will automatically be included and if the old ones are wanted they can be manually included in
ApplicationHelper
:This will make the old method variants override the new ones.
I will begin adding some warnings to the old ones before they are dropped.
Final things to do
options
andhtml_options
) can still be passed through to the Rails helpersvisually_hidden_prefix
andvisually_hidden_suffix
keyword arguments?