Skip to content

Commit d56188e

Browse files
committed
Update article content
1 parent c6f970e commit d56188e

File tree

1 file changed

+44
-42
lines changed

1 file changed

+44
-42
lines changed

app/content/pages/articles/how-to-render-css-dynamically-in-rails.html.mdrb

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -109,68 +109,70 @@ irb> Mime::SET.collect(&:to_s)
109109

110110
In Rails `mime_types.rb`, we can see the registered MIME types with each of their recognized extensions.
111111

112-
Here‘s the original `mime_types.rb`, added to Rails on Dec 2, 2006 ([source](https://github.com/rails/rails/blob/5410f2cb74737bd6d96c226230c2b9c2bfe1d80b/actionpack/lib/action_controller/mime_types.rb 'Source code on Github')).
113-
114-
```ruby:{"show_header": false}
115-
Mime::Type.register "*/*", :all
116-
Mime::Type.register "text/plain", :text
117-
Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml )
118-
Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript )
119-
Mime::Type.register "text/calendar", :ics
120-
Mime::Type.register "text/csv", :csv
121-
Mime::Type.register "application/xml", :xml, %w( text/xml application/x-xml )
122-
Mime::Type.register "application/rss+xml", :rss
123-
Mime::Type.register "application/atom+xml", :atom
124-
Mime::Type.register "application/x-yaml", :yaml, %w( text/yaml )
125-
```
112+
That `:css` in the MIME type registry is one way to instruct Rails controller behavior with `respond_to`.
126113

127-
Support for CSS added a short time later on Feb 17, 2007 ([commit](https://github.com/rails/rails/commit/392c7f7314d196c54912a65981d79002d032f896 'Commit on Github').
114+
Using `respond_to` in a controller allows you to define responses and logic based on the requested format. Here‘s how I take advantage of this behavior in `ColorSchemesController#show`:
128115

129-
```diff:{"show_header": false}
130-
+ Mime::Type.register "text/css", :css
131-
```
116+
<%= render CodeBlock::AppFile.new("app/controllers/color_schemes_controller.rb", lines: [1, 8..17], language: "ruby", revision: "bd53833b03c7f957546e5a9031643d3beb179beb") %>
132117

133-
That `:css` in the MIME type registry is one way to instruct Rails controller behavior with `respond_to`.
118+
This controller action will respond differently for HTML and CSS requests. To demonstrate the difference, I've inserted two iframes for `ColorSchemesController#show` below:
134119

135-
Using `respond_to` in a controller allows you to define responses and logic based on the requested format. As a contrived example, imagine a `Product#index` action that returns 25 products for an HTML request, e.g. `/products`, and loads 250 products for an RSS request, e.g. `/products.rss`.
120+
#### Iframe for HTML request
136121

137-
```ruby
138-
class ProductsController < ApplicationController
139-
def index
140-
respond_to do |format|
141-
format.html { @products = Product.limit(25) }
142-
format.rss { @products = Product.limit(250) }
143-
end
144-
end
145-
end
146-
```
122+
Below you‘ll see an `iframe` with `src` set to request the **Blue Chill** color scheme as `text/html`.
123+
124+
<%= tag.iframe src: color_scheme_path(@color_scheme_blue_chill) %>
147125

148-
To demonstrate the difference, I've inserted two requests to the `ColorScheme
126+
Here’s the code for the `iframe`:
149127

150128
```erb:{"show_header": false}
151129
<%= tag.iframe src: color_scheme_path(@color_scheme_blue_chill) %>
152130
```
153131

154-
<%= tag.iframe src: color_scheme_path(@color_scheme_blue_chill) %>
132+
#### Iframe for CSS request
133+
134+
And here you‘ll see an `iframe` with `src` set to request the **Blue Chill** color scheme as `text/css`.
135+
136+
<%= tag.iframe src: color_scheme_path(@color_scheme_blue_chill, format: :css) %>
137+
138+
Here’s the code for the `iframe`:
155139

156140
```erb:{"show_header": false}
157141
<%= tag.iframe src: color_scheme_path(@color_scheme_blue_chill, format: :css) %>
158142
```
159143

160-
<%= tag.iframe src: color_scheme_path(@color_scheme_blue_chill, format: :css) %>
144+
Behold: dynamic css from a controller action!
161145

162-
<%= turbo_frame_tag "syntax-highlight-form", src: settings_syntax_highlight_path(custom_syntax_highlight_params), class: "grid-cols-12 lg:grid-cols-12 m-bs-m" %>
163-
<noscript>
164-
JavaScript not enabled? Go to the <%= link_to "color scheme demo", settings_color_scheme_path(custom_color_scheme_params) %>. Then come back when you’re done.
165-
</noscript>
146+
And we can use this endpoint in a stylesheet `<link>` tag just like any other static CSS URL:
147+
148+
```html
149+
<%= stylesheet_link_tag color_scheme_path(@color_scheme, format: :css) %>
150+
```
151+
152+
A downside of moving our dynamic CSS to a separate controller action is that it requires an additional HTTP request. This might not be a big deal. But, for that same reason, we might also be able to take advantage of Rails conditional GET features to instruct HTTP proxies to cache the request if it hasn’t been modified:
153+
154+
<%= render CodeBlock::AppFile.new("app/controllers/color_schemes_controller.rb", lines: [1, 8..19], language: "ruby", revision: "c6f970e6c95787ab66c75f9d230734710084c9d2") %>
166155

167-
Generate Dynamic CSS from a Controller?
156+
Note the use of the `stale?` method here. This method will calculate a value for `Etag` or `Last-Modified` response headers and set the status to `304 Not Modified` if request headers match and the server doesn’t need to render anything.
168157

169-
Generating CSS dynamically from a controller offers several advantages:
158+
> Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache.
159+
>
160+
> [Source: Rails guides](https://guides.rubyonrails.org/caching_with_rails.html#conditional-get-support)
161+
162+
Using conditional GETs can help speed up the performance of such requests and lighten the workload on your Rails server.
163+
164+
## Recap
165+
166+
Rendering CSS inline
167+
168+
- Extra request isn‘t needed
169+
- More difficult to take advantage of long-lived caching
170+
171+
Rendering CSS in a controller
172+
173+
- Extra request isn‘t needed
174+
- More difficult to take advantage of long-lived caching
170175

171176
Flexibility: Allows for real-time style changes based on user preferences or application state.
172177
Customization: Enables user-specific or context-specific styling.
173178
Performance: Can reduce the overall CSS payload by serving only necessary styles.
174-
DRY principle: Avoids repetition in static stylesheets.
175-
176-
Step-by-Step Guide: Implementing Dynamic CSS Generation

0 commit comments

Comments
 (0)