用于CSS内部国际化的Rails(带有资产管道)的约定是什么?

时间:2013-04-26 21:14:40

标签: css ruby-on-rails twitter-bootstrap asset-pipeline

我知道CSS不应该有内容,但确实如此,就像来自Twitter Bootstrap文档CSS的这个好框(下面)extracted

box screen shot

/* Echo out a label for the example */
.bs-docs-example:after {
  content: "Example";
}

我不关心“示例”,我使用类似的东西作为mixin:

.box (@legend) {
  /* Echo out a label for the example */
  &:after {
    content: @legend;
  }
}

然后我不需要真正的动态CSS,我可以很容易地在一个类中包含mixin,但我不需要传递"Observation",而是需要传递t 'box.observation'

.observation {
  .box("<%= t 'box.observation' =>");
}

Rails应该遵循Conventions over Configuration,只需添加静态CSS / LESS / SCSS就很容易了,它已经包含在一个缩小的CSS中的所有页面中。国际化CSS的惯例是什么?例如,我应该把.observation的声明放在哪里?

2 个答案:

答案 0 :(得分:2)

我可以按照this answer中的建议为每个语言环境生成一个CSS,但由于除了I18n位之外的CSS是相同的,我会有以下任何一个:

  1. 具有大量静态CSS / LESS并且内联区域内联的文件夹,例如:

    /* en */
    .observation {
      .box("Observation");
    }
    
  2. 许多完全相同的动态CSS,例如

    /* en */
    html[lang=en] {
      .observation {
        .box("Observation")
      }
    }
    
  3. 相反,我选择创建一个CSS和ERB视图,并使用页面缓存和URL中的区域设置代码进行交付,这样就没有重复。请参阅下面的代码。

    配置/ routes.rb中

    X::Application.routes.draw do
      get 'index.:locale.:format' => 'css#index',
        constraints: { locale: /[a-z]{2}(-[A-Z]{2})?/,
                       format: 'css' }
    end
    

    应用程序/控制器/ css_controller.rb

    class CssController < ActionController::Base
      caches_page :index
      def index
        @locale = params[:locale]
      end
    end
    

    应用程序/视图/ CSS / index.css.less.erb

    @import "mixins";
    .observation {
      .box("<%= t 'box.observation', locale: @locale %>");
    }
    

    应用程序/资产/样式表/ mixins.less

    .box (@legend) {
      /* Echo out a label for the example */
      &:after {
        content: @legend;
      }
    }
    

    这个例子如果它是simple ERB view就会起作用,但由于它使用Less,我必须手动解析ERB和LESS,如同rails 4:

    class CssController < ActionController::Base
      caches_page :index
    
      def index
        @locale = params[:locale]
        erb_source  = find_template.source
        less_source = Tilt::ERBTemplate.new { erb_source }.render(self)
        css_source  = Less::Parser.new(paths: Rails.application.config.less.paths).parse(less_source).to_css
        render text: css_source
      end
    
      private
    
      def find_template(_action_name = action_name)
        lookup_context.disable_cache { lookup_context.find_template(_action_name, lookup_context.prefixes) }
      end
    end
    

答案 1 :(得分:2)

您不需要为每个区域设置生成新的CSS文件 - 这与疯狂相关。为什么你的CSS关心你网站的文字内容?

我认为你最好的选择是使用数据属性来获取价值......

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

然后在你的CSS中:

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

您可能会找到一种方法将其提取为部分(或帮助程序),以便您的erb文件最终结果如下:

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

辅助方法:

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