bridgetownrb / bridgetown

A next-generation progressive site generator & fullstack framework, powered by Ruby
https://www.bridgetownrb.com
MIT License
1.13k stars 114 forks source link

feat: Add hash attributes functionality to view tag helpers #537

Closed n-older closed 2 years ago

n-older commented 2 years ago

Summary

In Rails and other static site generators like Middleman, you can pass a data hash into helpers like link_to and image_tag whose key-value pairs will then be rendered as individual data attributes in the generated HTML. In Bridgetown, this will output a singular data attribute whose value is a hash-structured, JSON-esque string of all the key/value pairs (i.e. data="{:id=>"123", :name="John", :"created-at"=>"2022-04-20 13:11:31 -0400"}").

Motivation

This will be nice in more complex situations where link_to is required over a simple <a> tag and data attributes need to be attached.

Guide-level explanation

Reference-level explanation

Rails' <%= link_to %> lets you pass in optional arguments (generally HTML attributes) including, but not limited to, data attributes. The way in which you would pass in the data attributes would be structured as a hash, preferably in the Ruby > 1.9 syntax (i.e. data: { id: '123', name: 'John', 'created-at': Time.now }). See full example below:

This input:

<%= link_to 'About', '/about.html', data: { id: '123', name: 'John', 'created-at': Time.now } %>

would then output:

<a href="/about.html" data-id="123" data-name="John" data-created-at="2022-04-20 13:11:31 -0400">About</a>

Drawbacks

None come to mind.

Unresolved Questions

I don't know how possible this is, but it would be great to be able to use ActionView helpers from anywhere within the repo (where applicable).

jaredcwhite commented 2 years ago

I'll just add a note here that, technically, we won't be adding Action View as part of the rendering layer of Bridgetown. However, there's far more we can do to offer compatibility with common helpers that Rails users are accustomed to. I appreciate this issue to help us track that effort.

topofocus commented 2 years ago

Jared, don't get to cosy to »rails users«. A main feature of bridgetown is its obvious distance to »the rails way«. I do not like the bloating of active{something} libraries into the codebase. If somebody wants rails, its his choice. You choosed the roda way, please stay there!

Just the fact that rails implements »link_to« in that way does not mean, that we have to adapt it.

DRBragg commented 2 years ago

I dig this idea! Next time I have some free time for OS work I'm going to look into this

jaredcwhite commented 2 years ago

Jared, don't get to cosy to »rails users«.

I appreciate the sentiment, and I agree we shouldn't arbitrarily add features just because they happen to be in Rails. But if there are cases where a clear win can be had without any obvious downsides, it's worth considering IMHO.

DRBragg commented 2 years ago

@jaredcwhite just thinking this through some. I'm hoping to spend some time Friday working on it. I would imagine that what we want so for something like this:

<%= link_to "Label", "/foo/bar", class: "classes", data: { controller: "testable", action: "testable#test" } %>

to return:

<a href="/foo/bar" class="classes" data-controller="testable" data-action="testable#test">Label</a>

but I was wondering if we should also handle nested hashes. I run into this a lot with Stimulus controllers. So you'd be able to do:

<%= link_to "Label", "/foo/bar", class: "classes", data: { controller: "testable", action: "testable#test", testable: { target: "test_value", index_value: "1" } } %>

and get back:

<a href="/foo/bar" class="classes" data-controller="testable" data-action="testable#test" data-testable-target="test_value" data-testable-index-value="1">Label</a>

I'm not sure that serves much value outside of using stimulus controllers so I'm fine with not implementing it like that if you'd rather. I would like the feature though.

Thoughts?

jaredcwhite commented 2 years ago

@DRBragg I know it's a bit more work to handle the nesting and might not service too many different users…but based on the "principle of least surprise" I feel like it'd be worthwhile.