简体   繁体   中英

Rails - Adding assets and language files after the war has been deployed

I have a Rails (3.1.3 with asset pipeline) application that will be deployed as a war. This application has ui "themes". Internally, I just have .scss files (Sass) in the assets directory of the Rails application and I let the user switch between them.

I'd like to allow administrators to add themes(basically .scss files) to the application after it has been deployed as a war. How can I allow the functionality without requiring the war be rebuilt/recompiled (using warbler). Ideally, they would be able to add themes without having to do anything with the war file.

I have a similar concern for language files. How can someone dynamically add a language file to a deployed Rails application?

I'm currently pre-compiling assets, namely the themes written using Sass, in production, but I'm open to changing this if it'll helps solve this issue. Can I precompile asssets outside of the war? Is it possible to set the path of the asset pipeline to outside the war?

This is what comes to my mind.

You must be using some tomcat-apache-httpd combo

My sugesstion is to precompile the files and let apache serve the static content, do not add it to war.

once you feel that the content of the files needs to change , again precompile with latest content and replace it on server. it should not require the war to be redeployed

You will need to do some server config to serve static content from Apache and let other calls go to tomcat.

Precomplie the assets copy the public assets directory and store in somewhere else and configure apache to server all /assets from that dir

check how to configure mod_jk to serve static assets from apache

http://tomcat.apache.org/connectors-doc/webserver_howto/apache.html check the Configuring Apache to serve static web application files section

using proxypass

https://serverfault.com/questions/379667/apache-proxypass-ignore-static-files

https://serverfault.com/questions/156391/what-is-an-ideal-apache-tomcat-setup-with-apache-serving-static-assets

https://www.apachelounge.com/viewtopic.php?t=3907

regarding language files if they reside outside assets then I think as @pito suggested try using some database.

OR may be use same caching technique to cache the whole file by calling it from some another server and reloading the file cache if the file need to be updated by some admin.

Any code change will require war recompilation.

You can directly add files change files in WEPAPPS extracted dir after the war is extracted and restart tomcat but I think this is too risky for production environment.

I have not done it but I think is surely should work.

阅读Warbler似乎没有简单的解决方法,让应用程序通过数据库提供新的主题和语言

Disclaimer: I'm not familiar with WAR at all. My answer may be completely wrong because I have no experience with it. Please understand that I found this to be an interesting challenge and I wanted to find a solution.

I can't tell if when you create a WAR archive what the application is capable of doing. As a result I decided to use command line to do the actual compiling. However, it shouldn't be too difficult to include the sass gem and use the compiler directly if needed.

Because I rely on the command line you have to install the sass gem . Then see the README on using the command line interface.

For testing, I created a model called Theme with the following columns. You may need to change the code below to match the model you have in place.

  1. (string) title # the title of the theme
  2. (string) stylesheet_file_name # the name of the file that is saved

Inside of my form I used a different field name to prevent overlapping.

<%= f.form_field :styleheet %>

Then inside of my controller I added the code to compile the uploaded scss file and move it into the public directory.

def create
  if params[:theme].has_key?(:stylesheet)

    # create a filename friendly version of the theme name
    file_name = params[:theme][:stylesheet_file_name] = params[:theme][:title].parameterize

    # where to copy the temporary uploaded file to. It is important that we get
    # the original extension. The `sass` command uses the extension to determine how to compile the file
    tmp_file = "#{Rails.root}/tmp/#{params[:theme][:stylesheet].original_filename}"

    # move from /tmp path to within the Rails temp directory
    `cp #{params[:theme][:stylesheet].tempfile.path} #{tmp_file}`

    # create the theme's css file.
    File.open("#{Rails.root}/public/stylesheets/#{file_name}.css", 'w') do |f|

      # compile the .scss file via command line
      parsed_theme = `sass #{tmp_file}`

      # store the contents of the file
      f.write(parsed_theme)
    end

    # remove the temporary file we created earlier
    `rm #{tmp_file}`

    # this key wasn't part of my AR model
    params[:theme].delete("stylesheet")
  end

  # rest of action here ...
end

Once you have the css file in place you can include it in your layout/application.html.erb file with the following.

<head>
  <%= stylesheet_link_tag "/stylesheets/#{@current_theme.stylesheet_file_name}" %>
</head>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM