Access the Locale in Ruby in CSS Files

Access the Locale in Ruby in CSS files

You can add current locale to html tag as lang.
For example

%html{lang: I18n.locale}
<html lang="en"> or <html lang="ru">

and add specific language style with language prefix

html[lang="en"] {
# for english part
}

html[lang="ru"] {
# for russian part
}

also you can change behavior existing class

.test-title {
html[lang="en"] & {
// specific english style
}
}

Rails I18n of CSS file

Your best bet in organization is to have different style sheets specific to localization, then set up a condition in your layout on what style sheets to render based of the locale.

Just only put local specific style, and if you think about it...it shouldn't effect load times that much because I believe you are only changing font sizes.

UPDATE from OP:

Here is what I have configured to have this working:

  • I created a locales directory under app/assets/stylesheets
  • I put locale specific stylesheets inside, such as fr.sass
  • I setup the condition in the layouts/application.html.erb to reference the css files:

    <% if I18n.locale != :en %>
    <%= stylesheet_link_tag "locales/" + I18n.locale.to_s %>
    <% end %>
  • I setup the pre-compile rules in config/application.rb

config.assets.precompile += 'locales/*.css'

Note that I am white-listing the assets I want to compile into application.css, so the locale specific styles will not get into the application.css.

Loading different css files or images based on locale in Rails application

You can just reference the locale when including an asset. Let's say you want to include a stylesheet specific to the current locale :

stylesheet_link_tag "custom_#{I18n.locale}.css"

If the current locale is en, this will look for the custom_en.css file.

A word of warning though : you should make sure to create a file for each locale that you intend to use.

How can I put CSS style in my I18n locale?

If you want to add something fancy like this to your locale you must add the _html extension to the key.

From the docs

Keys with a '_html' suffix and keys named 'html' are marked as HTML
safe. When you use them in views the HTML will not be escaped.

en:
welcome_html: "<b>Bolded text</b>"

then just the regular stuff in your views

<%= t('welcome_html')

conditions in css fle?

It's probably not a good idea to make your base CSS file dynamic based on user/session/environment. You'll be busting your cache unnecessarily.

What you need in your base css is the just the default. The very nature of the CSS allows following declarations to override the previous.

So, in you application's layout file you would load the standard base CSS with background image handling the default locale.

For locale specific overrides, you would include a minimal CSS file for that specific locale OR if the amount of configuration per locale is minimal include the style inline in the header.

views/layouts/application.html.erb

<html>
<head>
<%= stylesheet_link_tag :defaults %> # Load standard base css here
<% if user_locale.present? %>
<style type="text/css">
#accordion .slide_handle {
background: url(<%= asset_url("handles-#{user_locale}.png") %>);
}
</style>
<% end %>
</head>
<body>
Yada Yada Yada
<%= yield %>
</body>
</html>

I seriously suggest you to follow a convention which allows your user's locale identifier to be the only decision maker for assets per locale.

If your locales are en,de,fr. Don't name your assets handle-1.png, handle-2.png but ensure they are handle-en.png, handle-de.png *handle-fr.png*. Following a convention will save you a bundle of pain of unnatural and brittle configuration to manage down the track.

Summary, Go for base default CSS, and override minimal css in the header section after including the base css. Alternatively you could include a locale specific css file which ONLY has overrides.

<head>
<%= stylesheet_link_tag :defaults %>
<%= stylesheet_link_tag "base-#{user_locale}" if user_locale.present? %>
</head>

Updated with another alternate solution:

<body class="<%= user_locale.presence || 'en' %>">
</body>

In your CSS list out all your overrides per locale with body parent like the following

body.en #accordion .slide_handle {
background: ....
}
body.de #accordion .slide_handle {
background: ...
}

You could split them into multiple locale specific files of keep it all together in one css, whichever you prefer. But this local overrides would be automatically applied to you layout without any further changes and all locales are always available at all times in your css (you may or may not find it appealing).

What is the convention in Rails (with asset pipeline) for internationalization inside CSS?

You don't need to generate a new CSS file for each locale - that borders on madness. Why does your CSS care about the text content of your website?

I think your best bet would be to use a data-attribute to grab the value...

<div class='bs-docs-example' data-before-content='<%= t.css_example %>'>
<!-- html here -->
</div>

And then in your css:

.bs-docs-example:after {
content: attr(data-before-content);
}

You could probably find a way to extract this into a partial (or helper), so that your erb file ends up like this:

<%= docs_example do %>
<!-- html here -->
<% end %>

And a helper method:

def docs_example
content_tag(:div, class: "bs-docs-example", "data-before-content" => t.css_example) do
yield
end
end

How to set font dynamically based on locale in rails?

Within the template, you can change the font based on locale by simply using the locale name as a CSS selector, as follows:

<body class="<%= I18n.locale %>">
...
</body>

and in your SASS file:

body {
.en {
$main-font: "Verdana"
}
.cn {
$main-font: "Microsoft_YaHei247019"
}
}


Related Topics



Leave a reply



Submit