2012-06-24 15 views
6

Ok, así que he convertido esta aplicación multicapa mía para hacer uso de la cartera de activos presentada en Rails 3.1. En su mayor parte ha sido sorprendentemente fácil y estoy enamorado de la capacidad de preprocesamiento que te permite usar Ruby en línea en tus archivos CSS/JS. Sin embargo, me he encontrado con un gran problema, que a pesar del poder de Sprockets parece difícil de resolver. Mi aplicación se puede ejecutar con cualquier número de máscaras (o "identidades" en su lugar) que se elige en tiempo de ejecución. Este parámetro de "identidad" configura cosas como el directorio de caché, la conexión a la base de datos, las rutas de vista y, de hecho, las rutas de los activos. Si bien todas las "identidades" pueden tener su propia hoja de estilo, también hay una compartida que se utiliza en todas las instancias. Por lo que la estructura de carpetas activos es como la siguiente:Canalización de activos de rieles: cómo incluir un activo que no está en la ruta del activo?

En /app/assets/stylesheets/aplication.css.erb:

<% require_asset("shared.css") %> 
<% require_asset("overrides.css") %> 

Esto carga dos hojas de estilo, y lo más importante que utiliza los caminos de activos configurados para resolver ellos (es por eso que uso require_assets en lugar de las directivas estándar require y include, ya que no llegan al resolver). Devuelve las primeras coincidencias encontradas y me permite anular fácilmente una parte o la totalidad del estilo predeterminado. Así

/app/assets/stylesheets/shared.css 

puede ser anulado por poner un archivo con el mismo nombre en la carpeta activos ejemplo

/app/assets/[identity]/stylesheets/shared.css 

y si no existe tal archivo en silencio en verano a la shared.css defecto.

Todo funciona de manera brillante: utilizo la misma técnica para Javascripts, imágenes y fuentes y todo se procesa y empaqueta ordenadamente durante la precompilación. PERO. Hay un tipo de herencia (lateral) que no puedo lograr; a veces la máscara de una identidad es muy similar a otra que solo unas pocas líneas dosen (p.ej. diseño idéntico pero con un esquema de color diferente) y realmente deseo poder hacer algo como esto:

activos /stylesheets/application.css.erb:

<% require_asset("shared.css") %> 
<% require_asset("overrides.css") %> 

activos/current_identity/hojas de estilo/overrides.css:

<% require_asset("../../some_other_identity/stylesheets/overrides.css") %> 
/* followed by the dosen or so lines that differ for this skin */ 
... 

esto no funciona debido a que en el contexto actual "some_other_identity" no está en el camino de activos s - Rails no encuentra el archivo en modo dev, y por supuesto tampoco está incluido durante la precompilación. Y si lo incluyo en la ruta de los activos carga el overrides.css incorrecto (solo puede haber un). Así que he estado experimentando con poner algo como esto en la parte superior de overrides.css:

<%= File.read(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css")) %> 
/* rest of CSS */ 
... 

Y en efecto, que funciona como se esperaba. PERO. Como ahora estoy usando la canalización de activos para servir a todos los activos, ya no puedo hacer referencia a las imágenes en el CSS con una ruta fija; tengo que usar <%= asset_path("some_image.png") %> para que el resolvedor de ruta pueda hacer su magia. Esto significa que mi overrides.css es realmente overrides.css.erb, y por supuesto el preprocesamiento de ERB no ocurre cuando haces File.read(). Entonces, ¡estoy atascado! ¡Ayuda! ¿Nadie?

Editar: Si uso

<%= ERB.new(File.read(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css.erb"))).result %> 

que sí trata de analizar la ERB, pero me da

undefined method `asset_path' for main:Object 

que por supuesto se debe a mí usando asset_path("some_image.png") etc en el archivo que he estoy tratando de incluir

+0

Pensé que quizás agregar la extensión .erb al nombre de archivo 'File.read()' lo resolvería (ya que está siendo incluido en un archivo que también es un archivo .erb) pero nunca es tan simple, ¿o sí? –

+0

Y tampoco es posible usar 'render()' - [vea esta pregunta] (http://stackoverflow.com/questions/8370399/rails-js-erb-file-cannot-find-method-render) –

Respuesta

5

Ok, después de horas de búsqueda me encontré con the list of available helper methods in Sprockets - me habría ahorrado mucho tiempo si esto hubiera sido vinculado desde the Sprockets man page en GitHub (hay un enlace, pero apunta a #FIXME). A partir de las ruedas dentadas de documentos de la API:

  • (Object) evaluate(path, options = {})
  • Lee path y corre procesadores en el archivo.
  • Esto le permite capturar el resultado de un activo e incluirlo directamente en otro.
  • <%= evaluate "bar.js" %>

Bingo! He cambiado de directiva include a:

<%= evaluate(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css.erb")) %> 

y el CSS se procesa y los resultados insertado, sólo la forma en que quería que funcione.

+0

Gracias para la referencia, me ayudó. –

Cuestiones relacionadas