Direct image_tag() to look in the current directory?

By default, image_tag() wants to grab images from /images as per config.rb. I see that I can put ./ in front of the image name to have it look in the current directory. Is there a way to have it look in the current directory and still generate full path names, perhaps through current_page?

Also, any way to get a list of image files in the current or some other directory?

You should be able to extract the base path to get the filename.

Inside config.rb:

helpers do

  def relative_path(path)
    basename = File.basename(current_page.path)
    File.join(basename, path)
  end

end

Inside your page:

<%= image_tag relative_path("logo.png"), alt: "A logo" %>

You could add a second helper to simplify the image_tag:

helpers do

  // ...

  def relative_image(path, *args, &block)
    image_tag(relative_path(path), *args, &block)
  end

end

And then the same example becomes:

<%= relative_image "logo.png", alt: "A logo" %>

To extract all the images in a directory, there are a couple of options.

First, you could use Dir.glob:

helpers do
  def files_in(dir, options = {})
    if options[:extensions]
      extensions = [options[:extensions]].flatten.compact.uniq
      options[:glob_pattern] = "**/*.{#{extensions.join(',')}}"
    end

    options[:glob_pattern] ||= "**/*"

    full_dir = File.join(source_dir, dir)
    file_pattern = File.join(full_dir, options[:glob_pattern])
    Dir.glob(file_pattern)
  end

  def image_paths_in(dir)
    image_paths = files_in(dir, extensions: %w{ jpg gif jpeg png })

    image_paths.map do |path|
      path.split(source_dir).last
    end
  end
end

Usage:

<% image_paths_in("images/icons").each do |path| %>
    <%= image_tag path %>
<%  end %>

Another way would be to look up the images through the known Middleman resources. I much prefer this, as it will play nicely with Middleman settings you might have that could affect the paths of images, but I’m not sure how well it will work for you if you aren’t using the defined images directory:

helpers do
  def image_resources_in(dir)
   image_exts = %w{ jpg gif jpeg png }

    sitemap.resources.select do |resource|
      resource_dir = File.dirname(resource.path)
      resource_ext = File.extname(resource.path).downcase
      dir == resource_dir && image_exts.include?(resource_ext)
    end
  end
end

Usage:

<% image_resources_in("images/icons").each do |image_resource| %>
    <%= image_tag image_resource.path %>
<%  end %>
3 Likes

This is fantastic and gives me ideas on how to address a couple other things that didn’t quite smell right with my first Middleman project!