Usando o pipeline de ativos do Rails 3.1 para usar condicionalmente determinadas CSS

166

Estou no processo de construção do meu primeiro aplicativo solo do Rails usando o Rails 3.1.rc5. Meu problema é que eu quero que meu site processe os vários arquivos CSS condicionalmente. Estou usando o CSS do Blueprint e estou tentando fazer com que as rodas dentadas / trilhos sejam processadas na screen.cssmaioria das vezes, print.cssapenas durante a impressão e ie.csssomente quando o site é acessado pelo Internet Explorer.

Infelizmente, o *= require_treecomando padrão no application.cssmanifesto inclui tudo no assets/stylesheetsdiretório e resulta em uma desordem desagradável de CSS. Minha solução atual é uma espécie de método de força bruta em que eu especifico tudo individualmente:

No application.css:

*= require_self
*= require home.css
...
*= require blueprint/screen.css

Nas minhas folhas de estilo parciais (haml):

<!--[if lt IE 9]
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
![endif]-->
= stylesheet_link_tag "application"
= stylesheet_link_tag 'blueprint/print', media: 'print'
<!--[if lt IE8]]
= stylesheet_link_tag 'blueprint/ie'
![endif]-->
= javascript_include_tag "application"

Isso funciona, mas não é especialmente bonito. Fiz algumas horas de pesquisa para chegar até aqui, mas espero que exista uma maneira mais fácil de fazer isso que acabei de perder. Se eu pudesse renderizar seletivamente certos diretórios (sem incluir subdiretórios), isso tornaria todo o processo muito menos rígido.

Obrigado!

talon55
fonte

Respostas:

223

Descobri uma maneira de torná-lo menos rígido e à prova do futuro ainda usando o pipeline de ativos, mas tendo as folhas de estilo agrupadas. Não é muito mais simples que a sua solução, mas essa solução permite adicionar automaticamente novas folhas de estilo sem precisar reeditar toda a estrutura novamente.

O que você quer fazer é usar arquivos de manifesto separados para separar as coisas. Primeiro você precisa reorganizar sua app/assets/stylesheetspasta:

app/assets/stylesheets
+-- all
    +-- your_base_stylesheet.css
+-- print
    +-- blueprint
        +-- print.css
    +-- your_print_stylesheet.css
+-- ie
    +-- blueprint
        + ie.css
    +-- your_ie_hacks.css
+-- application-all.css
+-- application-print.css
+-- application-ie.css

Em seguida, edite os três arquivos de manifesto:

/**
 * application-all.css
 *
 *= require_self
 *= require_tree ./all
 */

/**
 * application-print.css
 *
 *= require_self
 *= require_tree ./print
 */

/**
 * application-ie.css
 *
 *= require_self
 *= require_tree ./ie
 */

Em seguida, você atualiza o arquivo de layout do aplicativo:

<%= stylesheet_link_tag "application-all", :media => "all" %>
<%= stylesheet_link_tag "application-print", :media => "print" %>

<!--[if lte IE 8]>
    <%= stylesheet_link_tag "application-ie", :media => "all" %>
<![endif]-->

Por fim, não esqueça de incluir esses novos arquivos de manifesto em seu config / environment / production.rb:

config.assets.precompile += %w( application-all.css application-print.css application-ie.css )

Atualizar:

Como Max apontou, se você seguir essa estrutura, terá que estar atento às referências de imagem. Você tem poucas escolhas:

  1. Mova as imagens para seguir o mesmo padrão
    • Observe que isso só funciona se as imagens não forem todas compartilhadas
    • Espero que isso não seja de partida para a maioria, pois complica muito as coisas
  2. Qualifique o caminho da imagem:
    • background: url('/assets/image.png');
  3. Use o auxiliar SASS:
    • background: image-url('image.png');
gcastro
fonte
1
Embora seja uma boa organização dos arquivos, acredito que ainda resolve o problema essencial da mesma maneira que a própria pergunta.
Sempre # 8/11
@ Semperos, você está certo de que o formato da solução é essencialmente o mesmo, mas minha proposta ainda nos permite usar o pipeline de ativos para a totalidade das folhas de estilo. Não tenho certeza se existe outra maneira de incluir seletivamente parte dos estilos, a menos que esteja em uma folha de estilo separada. Pelo menos dessa forma, compilamos apenas um punhado de arquivos CSS.
gcastro
5
Algo assim no guia Rails Asset Pipeline seria bom, na verdade. obrigado
Bashar Abdullah
3
No entanto, existe um problema: se você seguir essa estrutura e usar .cssarquivos simples , todas as suas imagens serão quebradas. Por exemplo background: url('image.png'), será traduzido para o caminho /assets/all/image.png(lembre-se de tudo no caminho). Em vez isso funciona: background: url('/assets/image.png). Se houver uma solução mais fácil para isso, publique-a. Além de usar o SASS, que possui métodos auxiliares que provavelmente resolvem o caminho corretamente.
Max
1
@ExiRe, sim. Qualquer estilo ou JS arquivos / manifesta que não seguem a necessidade modelo padrão a ser adicionado à matriz de pré-compilação (ver: guides.rubyonrails.org/asset_pipeline.html#precompiling-assets )
gcastro
10

Me deparei com esse problema hoje.

Acabou colocando todas as folhas de estilo específicas do IE em lib / assets / stylesheets e criando um arquivo de manifesto por versão do IE. Em application.rb, adicione-os à lista de itens a serem pré-compilados:

config.assets.precompile += ["ie9.css", "ie7.css", "ie8.css", "ie.css"]

E em seus layouts, inclua condicionalmente esses arquivos de manifesto e você estará pronto!

Anthony Alberto
fonte