diff --git a/doc-src/content/CHANGELOG.markdown b/doc-src/content/CHANGELOG.markdown index 038f5096..0370eca9 100644 --- a/doc-src/content/CHANGELOG.markdown +++ b/doc-src/content/CHANGELOG.markdown @@ -14,14 +14,22 @@ The Documentation for the [latest stable release](http://compass-style.org/docs/ The Documentation for the [latest preview release](http://beta.compass-style.org/) -0.12.0 pending +0.12.0 (UNRELEASED) ------------------- * Added support for diagonal, horizontal, and smart sprite layout * Fixed a bug with spacing in horizontal layout * Changed the descriptions of the sin, cos, and tan to be more descriptive * Fixed trig functions via issue #498 * Fixed the default `http_path` in rails -* Sprites can now have a `sprite_seach_path` that is an array of directories that contain source images for sprites handy for using sprites in extensions of gems +* Sprites can now have a `sprite_seach_path` that is an array of directories that + contain source images for sprites handy for using sprites in extensions of gems +* Added a new set of configuration properties for generated images. + `generated_images_dir`, `generated_images_path`, `http_generated_images_dir`, + and `http_generated_images_path` can now be set to control where generated + images are written and how they are served. Added a corresponding + `generated-image-url()` helper function. These should rarely be needed and + will default to your corresponding image directories and paths. + 0.11.5 (07/10/2011) ------------------- diff --git a/doc-src/content/help/tutorials/configuration-reference.markdown b/doc-src/content/help/tutorials/configuration-reference.markdown index 02682243..66808bf7 100644 --- a/doc-src/content/help/tutorials/configuration-reference.markdown +++ b/doc-src/content/help/tutorials/configuration-reference.markdown @@ -170,11 +170,33 @@ later on. http_images_path - String + String The full http path to images on the web server. Defaults to http_path + "/" + images_dir. + + generated_images_dir + String + The directory where generated images are kept. + It is relative to the project_path. + Defaults to the value of images_dir. + + + + generated_images_path + String + The full path to where generated images are kept. + Defaults to the value of <project_path>/<generated_images_dir>. + + + + http_generated_images_path + String + The full http path to generated images on + the web server. Defaults to http_path + "/" + generated_images_dir. + + javascripts_dir String diff --git a/doc-src/content/reference/compass/helpers/urls.haml b/doc-src/content/reference/compass/helpers/urls.haml index da1d7853..961fbd44 100644 --- a/doc-src/content/reference/compass/helpers/urls.haml +++ b/doc-src/content/reference/compass/helpers/urls.haml @@ -12,6 +12,7 @@ documented_functions: - "stylesheet-url" - "font-url" - "image-url" + - "generated-image-url" --- %h1 Compass URL Helpers @@ -31,7 +32,7 @@ documented_functions: Generates a path to an asset found relative to the project's css directory. %br Passing a true value as the second argument will cause the only the path to be returned - instead of a `url()` function + instead of a url() function #font-url.helper %h3 @@ -42,7 +43,7 @@ documented_functions: Generates a path to an asset found relative to the project's font directory. %br Passing a true value as the second argument will cause the only the path to be returned - instead of a `url()` function + instead of a url() function #image-url.helper %h3 @@ -53,9 +54,27 @@ documented_functions: Generates a path to an asset found relative to the project's images directory. %p Passing a true value as the second argument will cause the only the path to be returned - instead of a `url()` function + instead of a url() function %p The third argument is used to control the cache buster on a per-use basis. - When set to `false` no cache buster will be used. When a string, that + When set to false no cache buster will be used. When a string, that value will be used as the cache buster. +#generated-image-url.helper + %h3 + %a(href="#generated-image-url") + generated-image-url($path, $cache-buster: false) + .details + %p + Generates a path to an image generated during compilation using the + generated_image related configuration properties. + %p + Most users will never call this helper directly, it is primarily provided + for use by plugins that need to generate paths to images they create. E.g. + The sprite-url() helper calls this helper. + %p + The second argument is used to control the cache buster on a per-use basis. + Defaults to false, meaning that no cache buster will be used. + When a string, that value will be used as the cache buster, when true + Compass will generate a cache-buster based on the image's modification time. + diff --git a/lib/compass/commands/clean_project.rb b/lib/compass/commands/clean_project.rb index e6792326..7a082380 100644 --- a/lib/compass/commands/clean_project.rb +++ b/lib/compass/commands/clean_project.rb @@ -30,7 +30,7 @@ module Compass def perform compiler = new_compiler_instance compiler.clean! - Compass::SpriteImporter.find_all_sprite_map_files(Compass.configuration.images_path).each do |sprite| + Compass::SpriteImporter.find_all_sprite_map_files(Compass.configuration.generated_images_path).each do |sprite| remove sprite end end diff --git a/lib/compass/configuration.rb b/lib/compass/configuration.rb index 91793a5c..7ad8291a 100644 --- a/lib/compass/configuration.rb +++ b/lib/compass/configuration.rb @@ -20,6 +20,7 @@ module Compass attributes_for_directory(:css, :stylesheets), attributes_for_directory(:sass, nil), attributes_for_directory(:images), + attributes_for_directory(:generated_images), attributes_for_directory(:javascripts), attributes_for_directory(:fonts), attributes_for_directory(:extensions, nil), diff --git a/lib/compass/configuration/defaults.rb b/lib/compass/configuration/defaults.rb index 97f8931e..2d6046c1 100644 --- a/lib/compass/configuration/defaults.rb +++ b/lib/compass/configuration/defaults.rb @@ -60,6 +60,14 @@ module Compass end end + def default_generated_images_path + if (pp = top_level.project_path) && (dir = top_level.generated_images_dir) + Compass.projectize(dir, pp) + else + top_level.images_path + end + end + def default_javascripts_path if (pp = top_level.project_path) && (dir = top_level.javascripts_dir) Compass.projectize(dir, pp) @@ -84,6 +92,13 @@ module Compass end end + def default_generated_images_dir + top_level.images_dir + end + + def default_http_generated_images_dir + top_level.http_images_dir + end def default_http_images_dir top_level.images_dir @@ -105,6 +120,10 @@ module Compass http_root_relative top_level.http_stylesheets_dir end + def default_http_generated_images_path + http_root_relative top_level.http_generated_images_dir + end + def default_http_fonts_dir if fd = top_level.fonts_dir_without_default fd diff --git a/lib/compass/sass_extensions/functions/sprites.rb b/lib/compass/sass_extensions/functions/sprites.rb index d2f74b61..03542ad0 100644 --- a/lib/compass/sass_extensions/functions/sprites.rb +++ b/lib/compass/sass_extensions/functions/sprites.rb @@ -96,9 +96,7 @@ module Compass::SassExtensions::Functions::Sprites def sprite_url(map) verify_map(map, "sprite-url") map.generate - image_url(Sass::Script::String.new("#{map.path}-s#{map.uniqueness_hash}.png"), - Sass::Script::Bool.new(false), - Sass::Script::Bool.new(false)) + generated_image_url(Sass::Script::String.new("#{map.path}-s#{map.uniqueness_hash}.png")) end Sass::Script::Functions.declare :sprite_url, [:map] diff --git a/lib/compass/sass_extensions/functions/urls.rb b/lib/compass/sass_extensions/functions/urls.rb index 50ffab52..581a080a 100644 --- a/lib/compass/sass_extensions/functions/urls.rb +++ b/lib/compass/sass_extensions/functions/urls.rb @@ -2,7 +2,7 @@ module Compass::SassExtensions::Functions::Urls def stylesheet_url(path, only_path = Sass::Script::Bool.new(false)) # Compute the path to the stylesheet, either root relative or stylesheet relative - # or nil if the http_images_path is not set in the configuration. + # or nil if the http_stylesheets_path is not set in the configuration. http_stylesheets_path = if relative? compute_relative_path(Compass.configuration.css_path) elsif Compass.configuration.http_stylesheets_path @@ -108,6 +108,61 @@ module Compass::SassExtensions::Functions::Urls Sass::Script::Functions.declare :image_url, [:path, :only_path] Sass::Script::Functions.declare :image_url, [:path, :only_path, :cache_buster] + def generated_image_url(path, cache_buster = Sass::Script::Bool.new(false)) + path = path.value # get to the string value of the literal. + + if path =~ %r{^#{Regexp.escape(Compass.configuration.http_generated_images_path)}/(.*)} + # Treat root relative urls (without a protocol) like normal if they start with + # the generated_images path. + path = $1 + elsif absolute_path?(path) + # Short curcuit if they have provided an absolute url. + return Sass::Script::String.new("url(#{path})") + end + + # Compute the path to the image, either root relative or stylesheet relative + # or nil if the http_generated_images_path is not set in the configuration. + http_generated_images_path = if relative? + compute_relative_path(Compass.configuration.generated_images_path) + elsif Compass.configuration.http_generated_images_path + Compass.configuration.http_generated_images_path + else + Compass.configuration.http_root_relative(Compass.configuration.generated_images_dir) + end + + # Compute the real path to the image on the file stystem if the generated_images_dir is set. + real_path = if Compass.configuration.generated_images_dir + File.join(Compass.configuration.project_path, Compass.configuration.generated_images_dir, path) + end + + # prepend the path to the image if there's one + if http_generated_images_path + http_generated_images_path = "#{http_generated_images_path}/" unless http_generated_images_path[-1..-1] == "/" + path = "#{http_generated_images_path}#{path}" + end + + # Compute the asset host unless in relative mode. + asset_host = if !relative? && Compass.configuration.asset_host + Compass.configuration.asset_host.call(path) + end + + # Compute and append the cache buster if there is one. + if cache_buster.to_bool + if cache_buster.is_a?(Sass::Script::String) + path += "?#{cache_buster.value}" + else + path = cache_busted_path(path, real_path) + end + end + + # prepend the asset host if there is one. + path = "#{asset_host}#{'/' unless path[0..0] == "/"}#{path}" if asset_host + + clean_url(path) + end + Sass::Script::Functions.declare :generated_image_url, [:path] + Sass::Script::Functions.declare :generated_image_url, [:path, :cache_buster] + private # Emits a path, taking off any leading "./" diff --git a/lib/compass/sass_extensions/sprites/sprite_methods.rb b/lib/compass/sass_extensions/sprites/sprite_methods.rb index 7fdec149..36cf76ed 100644 --- a/lib/compass/sass_extensions/sprites/sprite_methods.rb +++ b/lib/compass/sass_extensions/sprites/sprite_methods.rb @@ -43,7 +43,7 @@ module Compass # The on-the-disk filename of the sprite def filename - File.join(Compass.configuration.images_path, "#{path}-s#{uniqueness_hash}.png") + File.join(Compass.configuration.generated_images_path, "#{path}-s#{uniqueness_hash}.png") end # Generate a sprite image if necessary @@ -87,6 +87,7 @@ module Compass # Saves the sprite engine def save! + FileUtils.mkdir_p(File.dirname(filename)) saved = engine.save(filename) Compass.configuration.run_callback(:sprite_saved, filename) saved diff --git a/test/integrations/sprites_test.rb b/test/integrations/sprites_test.rb index 3db8e640..e099bc05 100644 --- a/test/integrations/sprites_test.rb +++ b/test/integrations/sprites_test.rb @@ -11,6 +11,7 @@ class SpritesTest < Test::Unit::TestCase Compass.reset_configuration! @images_src_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'sprites', 'public', 'images') @images_tmp_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'sprites', 'public', 'images-tmp') + @generated_images_tmp_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'sprites', 'public', 'generated-images-tmp') ::FileUtils.cp_r @images_src_path, @images_tmp_path file = StringIO.new("images_path = #{@images_tmp_path.inspect}\n") Compass.add_configuration(file, "sprite_config") @@ -20,6 +21,7 @@ class SpritesTest < Test::Unit::TestCase def teardown Compass.reset_configuration! ::FileUtils.rm_r @images_tmp_path + ::FileUtils.rm_rf @generated_images_tmp_path end @@ -74,6 +76,35 @@ class SpritesTest < Test::Unit::TestCase assert_equal image_md5('squares-s*.png'), '7349a0f4e88ea80abddcf6ac2486abe3' end + it "should output and serve sprite files using the generated images directory" do + Compass.reset_configuration! + file = StringIO.new(<<-CONFIG) + images_path = #{@images_tmp_path.inspect} + generated_images_path = #{@generated_images_tmp_path.inspect} + http_generated_images_path = "/images/generated" + CONFIG + Compass.add_configuration(file, "sprite_config") + Compass.configure_sass_plugin! + css = render <<-SCSS + @import "squares/*.png"; + @include all-squares-sprites; + SCSS + assert_not_nil Dir.glob("#{@generated_images_tmp_path}/squares-s*.png").first + assert_correct <<-CSS, css + .squares-sprite, .squares-ten-by-ten, .squares-twenty-by-twenty { + background: url('/images/generated/squares-s161c60ad78.png') no-repeat; + } + + .squares-ten-by-ten { + background-position: 0 0; + } + + .squares-twenty-by-twenty { + background-position: 0 -10px; + } + CSS + end + it "should generate sprite classes with dimensions" do css = render <<-SCSS $squares-sprite-dimensions: true;