Как использовать ссылочные изображения в Sass при использовании Rails 3.1?

У меня есть проект Rails 3.1, работающий отлично. Проблема в том, что мне нужно ссылаться на изображения в моем Sass, но Rails вычисляет URL-адреса изображений. (Это особенно важно при производстве, когда Rails добавляет хэш файл Git изображения к его имени файла для перебора кешей.)

Например, в app/assets/stylesheets/todos.css.scss:

.button.checkable { background-image: url(/assets/tick.png); }

Когда я развертываю (или запускаю rake assets:precompile), файл app/assets/images/tick.png перемещается в public/assets/tick-48fe85c0a.png или что-то подобное. Это нарушает CSS. Этот пост содержит два предложения:

  • не используйте конвейер объектов для изображений - вместо этого разместите их в public/images/ и обратитесь к ним напрямую
  • используйте ERB для вашего CSS и пусть Rails разработает URL-адрес изображения.

Номер 1 - это, конечно, возможность, хотя это означает, что я не получаю кэширование на своих изображениях. Номер 2 отсутствует, потому что я использую Sass, а не ERB для обработки файлов.

Ответ 1

Следующее должно сделать трюк:

.button.checkable { background-image: url(image_path('tick.png')); }

Рельсы на самом деле предоставляют кучу помощников для ссылки на активы:

image-url('asset_name')
audio-path('asset_name')

В общем

[asset_type]-url('asset_name') #Becomes url('assets/asset_name')
[asset_type]-path('asset_name') #Becomes 'assets/asset_name'

asset_type может быть одним из следующих: образ, шрифт, видео, аудио, javascript, таблица стилей

Ответ 2

sass-rails gem определяет функции Sass, которые могут использоваться от Sass без обработки ERB. https://github.com/rails/sass-rails

Ответ 3

Для тех, кто выступает за более быстрое время загрузки для пользователей, могу ли я предложить следующий совет Стива Соудерса для загрузки изображений в CSS в base64.

активов данных URL ( 'путь')

https://github.com/rails/sass-rails#asset-helpers

Ответ 4

Вариант варианта 2 будет работать. Если у вас есть что-то вроде этого:

app/assets/stylesheets/pancakes_house.css.less.erb

И вы require в свой application.css файл. Затем pancakes_house сначала проходит через ERB, и этот выход проходит через процессор LESS, и все, что выходит из этого, входит в ваш CSS. Ввод ERB внутри вашего SCSS может показаться немного странным, но, эй, он будет работать и выполнять работу без излишней странности.

Итак, вы должны иметь возможность получить необходимые методы для создания путей кэш-распаковки изображений через ваш ERB.

Я только пробовал это с файлом Less, но он также должен работать с .css.scss.erb.


В качестве альтернативы вы также можете добавить свои собственные функции в SASS:

Методы в этом модуле доступны из контекста SassScript. Например, вы можете написать

$color = hsl(120deg, 100%, 50%)

и он вызовет Sass::Script::Functions#hsl.

Есть даже некоторые инструкции по написанию собственных функций чуть дальше в руководстве. Однако я не уверен, как заставить Sprockets загружать ваши патчи Sass::Script::Functions, поэтому я не могу назвать это практическим решением; кто-то с более сильным Sprocket Fu, чем я, мог бы заставить этот подход работать, хотя я бы назвал это более элегантным, чем ERBified SCSS.

Ответ 5

Вы можете легко использовать номер 2, просто добавьте расширение .erb в файл .scss:

app/assets/stylesheets/todos.css.scss.erb

и используйте метод asset_path, чтобы получить путь к изображению с хешем:

.button.checkable { background-image: url('<%= asset_path 'tick.png' %>'); }

этот файл будет обработан erb, а затем sass.

Ответ 6

При использовании конвейера ресурсов пути к активам должны быть переписаны, а sass-rails предоставляет помощники -url и -path (переносимые в Sass, подчеркнутые в Ruby) для следующих классов активов: изображение, шрифт, видео, аудио, JavaScript и таблицы стилей.

image-url ( "rails.png" ) возвращает url (/assets/rails.png)  image-path ( "rails.png" ) возвращает "/assets/rails.png"

Можно также использовать более общую форму:

asset-url ( "rails.png" ) возвращает url (/assets/rails.png)  resource-path ( "rails.png" ) возвращает "/assets/rails.png"