Mailinglist Archive: opensuse-ruby (15 mails)

< Previous Next >
[opensuse-ruby] javascript and static assets
  • From: "Duncan Mac-Vicar Prett" <dmacvicar@xxxxxxx>
  • Date: Thu, 10 Dec 2009 11:20:41 +0100
  • Message-id: <200912101120.41482.dmacvicar@xxxxxxx>

Hi

One of the first problems we hit by using the Rails 2.3 engine was the usage
of the static files directory.

Engines do not support their own public/ directory. This is because rails does
not serve it, but the http server directly.

This means that even if our engines are under plugins/$foo, the static files
like images and _javascript_files_ have to go under the main app public/
braking this structure.

As we are a packaged application, where files should not be touched manually,
and the application files should be read only and immutable (so the original
engines sync task was not an option), we still needed to provide the vendors
with the ability to override any file to alter the look and feel. Like for
example, dropping a new css file with the same name somewhere to be used
instead of the main one. This was achieved by a small hack:

# In order to overwrite,exchange images, stylesheets,.... for special vendors
there
# is the directory "vendor" in the "public" directory. Each file in the public
# directory can be exchanged by putting a file with the same path in the
vendor
# directory.
# Please take care that all links in the views have to be defined by the
AssetTagHelper like
# image_tag, stylesheet_link_tag, javascript_include_tag, ...
config.action_controller.asset_host = Proc.new do |source, request|
path = "#{config.root_path}/public/vendor#{source}".split("?")
if path.length >0 and File.exists?(path[0])
"#{request.protocol}#{request.host_with_port}/vendor"
else
""
end
end

The ability for plugins to have their own public directory was solved by using
a rack middle-ware, but this only worked in development mode, because in a
normal setup, the http server was the first in the rack chain.

# look for all existing loaded plugin's public/ directories
plugin_assets = init.loaded_plugins.map { |plugin| File.join(plugin.directory,
'public') }.reject { |dir| not (File.directory?(dir) and File.exist?(dir)) }
init.configuration.middleware.use YaST::Rack::StaticOverlay, :roots =>
plugin_assets

This problem hits bad on javascript files. Right now if we want to have a
separate javascrpt file that decorates/validates/autocompletes a view, it
needs to go in the main app public directory. Which means you can have it
together with the other files. When packaging it, it can be installed there,
but while running in development mode you just want to edit the file and
reload.

So I am looking for ways to solve this problem. Right now most of the views
javascript is just inlined, which is not good. There are even nice plugins
like this one:

http://blog.media72.net/2008/05/13/javascript-auto-include-rails-plugin/

Which auto includes javascript files based on the name of the view (convention
over configuration) so you don't even need to include the files from your
views explicitly, but this still requires those files to be in public/

The only idea that is going around my head is actually serving those files
from rails, having a kind of asset controller that could look into the
filesystem and read the files. For us the performance of the http server is
not that critical like it is for a heavy multiuser site.

Is the problem understood? (I can try to explain more). Does anyone has
experiences or ideas on this?

--
Duncan Mac-Vicar P. - Engineering Manager, YaST
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nuernberg)

--
To unsubscribe, e-mail: opensuse-ruby+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: opensuse-ruby+help@xxxxxxxxxxxx

< Previous Next >
Follow Ups