Search code examples
htmlruby-on-rails-4application-cache

How to create a rails 4 offline webapp?


I'm trying to create an app with Rails 4 that should be usable without internet connection. I've heard about html5 application cache and the rack-offline gem which is the approach I took. Now, it seems that it's not working properly on Rails 4 since the /application.manifest only shows:

CACHE MANIFEST
# dd1ba6bba9339ef83f9c1225c70289dd6326d3caae01b0d52b502381030dc78f

404.html
422.html
500.html

NETWORK:
*

Also, I'm using assets precompile so the application.js, application.css and the image files has a fingerprint in their names, something like application-e8cc2fba8275c884c.js.


Solution

  • I made my own solution in a generate_appcahe_manifest.rake file and put it in /lib/tasks folder.

    task :generate_appcache_file => ['deploy:precompile_assets', 'html5_manifest']
    
    desc "Create html5 manifest.appcache"
    task :html5_manifest => :environment do
      puts 'Creating appcache manifest file...'
    
      File.open("public/manifest.appcache", "w") do |f|
        f.write("CACHE MANIFEST\n")
        f.write("# Version #{Time.now.to_i}\n\n")
        f.write("CACHE:\n")
        assets = Dir.glob(File.join(Rails.root, 'public/assets/**/*'))
        assets.each do |asset|
          if File.extname(asset) != '.gz' && File.extname(asset) != '' && File.extname(asset) != '.json'
            filename_path = /#{Rails.root.to_s}\/public\/(assets\/.*)/.match(File.absolute_path(asset))[1].to_s
            # f.write("assets/#{File.basename(asset)}\n")
            f.write(filename_path.concat("\n"))
          end
        end
        f.write("\nNETWORK:\n")
        f.write("*\n")
        f.write("http://*\n")
        f.write("https://*\n")
      end
      puts 'Done.'
    end
    
    namespace :deploy do
      task :precompile_assets do
        require 'fileutils'
        if File.directory?("#{Rails.root.to_s}/public/assets")
          FileUtils.rm_r "#{Rails.root.to_s}/public/assets"
        end
    
        puts 'Precompiling assets...'
        puts `RAILS_ENV=production bundle exec rake assets:precompile`
        puts 'Done.'
      end
    end
    

    So when I run rake generate_appcache_file on the terminal, I got a /public/manifest.appcache file with the compiled assets like this:

    CACHE MANIFEST
    # Version 1409045103
    
    CACHE:
    
    assets/app/backgrounds/strips-05561384267a3286ab382c852f1e8b0d.jpg
    assets/app/backgrounds/team-12e0fc5f670794c4eba3db117fba6746.jpg
    assets/app-a7de6b02d1d39b783fe4e7ab7906ec95.css
    assets/app-ae958853aa13f9011e35121cbe5b3cfe.js
    
    NETWORK:
    *
    http://*
    https://*
    

    Finally, I call that file on my /app/views/layouts/app.html.erb file:

    <!DOCTYPE html>
    <html lang="en" manifest="/manifest.appcache">
    

    More info about offline application cache that helps me a lot can be found here.