Coder Social home page Coder Social logo

sprockets-helpers's Introduction

sprockets-helpers

Asset path helpers for Sprockets 4.x & 3.x & <= 2.2 applications

Sprockets::Helpers adds the asset_path helpers, familiar to Rails developers, to Sprockets 2.x assets and applications.

Features

  • Includes helpers for image, javascript, stylesheet, font, video, & audio assets.
  • Automatically appends extension if necessary.
  • Optionally outputs digest paths.
  • Falls back to file paths in the public directory & adds cache busting timestamp.

Installation

$ gem install sprockets-helpers

Setup

Let's build a simple Sinatra app using Sprockets and Sprockets::Helpers (See my fork of sinatra-asset-pipeline for complete setup):

require 'sinatra/base'
require 'sprockets'
require 'sprockets-helpers'

class App < Sinatra::Base
  set :sprockets, Sprockets::Environment.new(root)
  set :assets_prefix, '/assets'
  set :digest_assets, false

  configure do
    # Setup Sprockets
    sprockets.append_path File.join(root, 'assets', 'stylesheets')
    sprockets.append_path File.join(root, 'assets', 'javascripts')
    sprockets.append_path File.join(root, 'assets', 'images')

    # Configure Sprockets::Helpers (if necessary)
    Sprockets::Helpers.configure do |config|
      config.environment = sprockets
      config.prefix      = assets_prefix
      config.digest      = digest_assets
      config.public_path = public_folder

      # Force to debug mode in development mode
      # Debug mode automatically sets
      # expand = true, digest = false, manifest = false
      config.debug       = true if development?
    end
  end

  helpers do
    include Sprockets::Helpers

    # Alternative method for telling Sprockets::Helpers which
    # Sprockets environment to use.
    # def assets_environment
    #   settings.sprockets
    # end
  end

  get '/' do
    erb :index
  end
end

Usage in Assets

Simply requiring sprockets-helpers will add the asset path helpers to the Sprocket context, making them available within any asset. For example, a file assets/javascripts/paths.js.erb:

var Paths = { railsImage: "<%= image_path 'rails.png' %>" };

Would be transformed into:

var Paths = { railsImage: '/assets/rails.png' };

Usage in the App

The helpers can also be used in the app itself. You just include the Sprockets::Helpers module and set Sprockets::Helpers.environment to the Sprockets environment to search for the assets. Alternatively you can define an #assets_environment method in the context of #asset_path, which returns a reference to the Sprockets environment (see above).

Now the following index file:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Sinatra with Sprockets 2 (Asset Pipeline)</title>
    <link rel="stylesheet" href="<%= stylesheet_path 'application' %>">
    <script src="<%= javascript_path 'application' %>"></script>
  </head>
  <body>
    <img src="<%= image_path 'rails.png' %>">
  </body>
</html>

Would become:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Sinatra with Sprockets 2 (Asset Pipeline)</title>
    <link rel="stylesheet" href="/assets/application.css">
    <script src="/assets/application.js"></script>
  </head>
  <body>
    <img src="/assets/rails.png">
  </body>
</html>

Even better, you can use #javascript_tag and #stylesheet_tag directly, which optionally handle the expansion of assets for debugging like Rails:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Sinatra with Sprockets 2 (Asset Pipeline)</title>
    <%= stylesheet_tag 'application' %>
    <%= javascript_tag 'application', :expand => true %>
  </head>
  <body>
    <img src="<%= image_path 'rails.png' %>">
  </body>
</html>

Would become:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Sinatra with Sprockets 2 (Asset Pipeline)</title>
    <link rel="stylesheet" href="/assets/application.css">
    <script src="/assets/jquery.js?body=1"></script>
    <script src="/assets/jquery.ui.js?body=1"></script>
    <script src="/assets/application.js?body=1"></script>
  </head>
  <body>
    <img src="/assets/rails.png">
  </body>
</html>

Fallback to Public Directory

If the source is not an asset in the Sprockets environment, Sprockets::Helpers will fallback to looking for the file in the application's public directory. It will also append the cache busting timestamp of the file. For example:

Given an image, public/images/logo.jpg:

<img src="<%= image_path 'logo.jpg' %>">

Would become:

<img src='/images/logo.jpg?1320093919'>

Manifest Usage

Sprockets::Helpers will use the latest fingerprinted filename directly from a manifest.json file:

# ...
Sprockets::Helpers.configure do |config|
  config.environment = sprockets
  config.manifest    = Sprockets::Manifest.new(sprockets, 'path/to/manifset.json')
  config.prefix      = assets_prefix
  config.public_path = public_folder
end
# ...

Sinatra Integration

New in 1.0: there is an easier way to integrate with Sinatra applications. You can register the Sinatra::Sprockets::Helpers extension and it will automatically include the helpers:

require 'sinatra/base'
require 'sprockets'
require 'sinatra/sprockets-helpers'

class App < Sinatra::Base
  register Sinatra::Sprockets::Helpers
  set :sprockets, Sprockets::Environment.new(root)
  set :assets_prefix, '/assets'
  set :digest_assets, true

  configure do
    # Setup Sprockets
    sprockets.append_path File.join(root, 'assets', 'stylesheets')
    sprockets.append_path File.join(root, 'assets', 'javascripts')
    sprockets.append_path File.join(root, 'assets', 'images')

    configure_sprockets_helpers do |helpers|
      # This will automatically configure Sprockets::Helpers based on the
      # `sprockets`, `public_folder`, `assets_prefix`, and `digest_assets`
      # settings if they exist. Otherwise you can configure as normal:
      helpers.asset_host = 'some-bucket.s3.amazon.com'
    end
  end

  get '/' do
    erb :index
  end
end

Roda Integration

See: https://github.com/hmdne/roda-sprockets

Copyright

Copyright (c) 2011 Peter Browne. See LICENSE for details.

sprockets-helpers's People

Contributors

antifuchs avatar dometto avatar dwradcliffe avatar hmdne avatar icambron avatar kathgironpe avatar loe avatar petebrowne avatar pkrefta avatar steel avatar timmfin avatar toomanybees avatar trkoch avatar vitorhp avatar yasuoza avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sprockets-helpers's Issues

javascript_tag helper conflict

Is there a reason you used javascript_tag instead of javascript_include_tag? I'm finding that other gems are trying to use javascript_tag to include a script tag with content and I can't because this gem has overwritten that helper.

Offending code:

def javascript_tag(source, options = {})
options = Helpers.default_path_options[:javascript_path].merge(options)
asset_tag(source, options) do |path|
%Q(<script src="#{path}"></script>)
end
end

It would make more sense to me to leave javascript_tag alone.

File in the public folder doesn't have priority

Hey!

I'm trying to migrate my single page app to sinatra instead of rails.
I want to compile my assets before deployment in production so I've written a short Rakefile that does this.

However, the files in my public/assets are never served, they are always generated on the fly.

Here's my app.rb:

require 'bundler'
Bundler.require

require 'sinatra'

class App < Sinatra::Base
  set :root, File.dirname(__FILE__)
  set :static, true
  set :public_folder, Proc.new { File.join(root, "public") }
  set :env, (ENV['RACK_ENV'] || 'development').to_sym
  set :sprockets, Sprockets::Environment.new(root)
  set :assets_prefix, '/assets'
  set :digest_assets, true
  set :assets_path, Proc.new { File.join public_folder, assets_prefix }

  configure do
    sprockets.append_path File.dirname(HamlCoffeeAssets.helpers_path)
    sprockets.append_path File.join(root, 'assets', 'stylesheets')
    sprockets.append_path File.join(root, 'assets', 'javascripts')
    sprockets.append_path File.join(root, 'assets', 'images')

    Sprockets::Helpers.configure do |config|
      config.environment = sprockets
      config.digest      = digest_assets
      config.prefix      = assets_prefix
      config.public_path = public_folder
    end
  end

  helpers do
    include Sprockets::Helpers
  end

  get '/*' do
    haml :home
  end
end

I do realize that this might just be a config issue but I think this settings should be default.

:expand is including all of the source files in the main file duplicating source.

In my layout.haml file, I have this:

    != javascript_tag 'ipt'

And assets/javascripts/ipt.js.coffee includes a bunch of other coffee/js files via the sprocket directives. In debug mode, all of these files are of course loaded separately, however, at the end of the list, it is also loading 'ipt.js' which has all of the source from the directives again which is causing errors.

A quick cursory glance at the source doesn't show what I'm missing here. Any ideas?

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

  spec.license = 'MIT'
  # or
  spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

Set prefix doesn't work properly

Hi there,
it seems to be set prefix doesn't work.

stylesheet_path('base') method returns /stylesheets/base.css instead of /assets/stylesheets/base.css even a prefix is set

My code is the following

Sprockets::Helpers.configure do |config|
  config.environment = sprockets_environment
  config.prefix      = '/assets'
  config.public_path = public_folder
end
Sprockets::Environment.new.tap do |environment|
   environment.append_path 'app/assets'
end

The structure of my assets folder

my_app
  |- app
    |- assets
      |- stylesheets
      |- javascripts
      |- images

I think there is a problem in this part of lib/sprockets/helpers.rb file:

# If the source points to an asset in the Sprockets
# environment use AssetPath to generate the full path.
assets_environment.resolve(uri.path) do |path|
  return AssetPath.new(uri, assets_environment[path], options).to_s
end

This part is returned instead:

# Use FilePath for normal files on the file system
FilePath.new(uri, options).to_s

Support for urls? (config.action_controller.asset_host)

Does this support asset hosts?

I was looking for something that could return the full url of a image:

config.action_controller.asset_host = "http://assets%d.app.com"
...
image_url('/image.jpg')
# http://assets1.app.com/image.jpg

error occurred when use sprockets-helpers as sinatra helper

def append_features(context) # :nodoc:
        context.class_eval do
          Helpers.public_instance_methods.each do |method|
            remove_method(method) if method_defined?(method)
          end
        end

        super(context)
      end

sinatra helpers not defined in Sinatra::Base, but just mix-in from a module.

So method_defined(method)? return true, but remove_method(method) throw exceptions...wish you fix it

Issue with registering helpers

Hey there!

It's first time I use Sinatra and for dealing with assets I found your gem. I did everything described in "New in 1.0" section and it didn't work.

class App < Sinatra::Base
  register Sinatra::Sprockets::Helpers
  set :sprockets, Sprockets::Environment.new(root)
  set :assets_prefix, '/assets'
  set :digest_assets, true

  configure do
    # Setup Sprockets
    sprockets.append_path File.join(root, 'assets', 'stylesheets')
    sprockets.append_path File.join(root, 'assets', 'javascripts')
    sprockets.append_path File.join(root, 'assets', 'images')

    configure_sprockets_helpers do |helpers|
      helpers.asset_host = 'some-bucket.s3.amazon.com'
    end
  end

You have a comment there that says it will use 'sprockets', 'public_folder', 'assets_prefix', and 'digest_assets' variables to set up helpers but at least for me, those variables are not defined in time because calling register Sinatra::Sprockets::Helpers happens before those variables are set. Moving this line after setting variables fixes this for me. Am I doing something wrong?

Thanks in advance,
Sergey

InvalidURIError if assets_path is not defined

I get a lot of errors after upgrading.

Here's one issue:

  1. If assets_prefix is not defined, I get URI::InvalidURIError which I have temporarily fixed in a non-elegant manner.

  2. If assets_prefix is defined as suggested on the README file, I get another error:

    NoMethodError: undefined method `each' for "/assets":String
    
  3. Trying to keep that an array doesn't help and still throws URI::InvalidURIError

Including Sprockets::Helpers doesn't seem to work anymore

Hi again Pete! Sorry for opening tickets left and right :/

I think that as of 0.7.0 the asset_path methods aren't actually available to Sprockets::Helpers and therefore don't get pulled in to the Sinatra app when calling include Sprockets::Helpers. If you pull down https://github.com/l3ck/sinatra-boilerplate/tree/testing-sprockets and fire it up (bundle then rake s) you should get the error "undefined method 'image_path'" which is being called on line 8 of layout.erb.

If I knew more about class evaluation I'd have included a pull request as well but I'm woefully lacking in that area. It looks like the Helpers module just needs a way to access the Context class' methods right?

Here's a stack dump from my side as well: https://gist.github.com/3783430

Thank you!

Can't configure sprockets helpers for more than one server at a time

I'm currently trying to run two Sinatra apps with sprockets-helpers configured in the same EventMachine event loop, but since the helpers configuration is kept on the global Helpers object, only one set of settings will stick.

I think with the sinatra layer at least, there's a great opportunity to store the Helpers config local to the app and not globally. I'll submit a PR for this once I've got an implementation of it fleshed out.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.