Search code examples
ruby-on-railsasset-pipelineassets

Separate frontend assets from admin assets


I'd like some feedback if possible. I have a rails app with this folder structure

rails
- app
-- controllers
--- admin
--- front

So basically I have cotrollers on both front and admin namespace. However the assets have the default setting at the moment, like this

assets
- stylesheets
- javascripts

so application.scss loads all css for both front and admin

*
*= require_tree .
*= require_self

How can I specify the front layout to load only assets required for the frontend (and not admin) and the admin layout to load only the admin assets and not front assets?


Solution

  • You can create two manifest files (instead of using the default application.js/application.scss) and include them in different layouts (one for front and one for admin).

    For example, you could you use this folder structure:

    assets
    - javascripts
    -- admin
    -- front
    - stylesheets
    -- admin
    -- front
    - admin.scss
    - front.scss
    

    Inside each admin/front folder you can add the specific styles/scripts needed, then ensure your manifest files look like this (only showing styles manifests, same goes for scripts):

    admin.scss

    /*
     * Manifest file for admin styles, to be compiled into admin.scss
     *
     *= require_self
     *= require_tree ./admin
     */
    

    front.scss

    /*
     * Manifest file for front styles, to be compiled into front.scss
     *
     *= require_self
     *= require_tree ./front
     */
    

    Now you must create your layouts (in app/views/layouts):

    admin.html.erb

    <!DOCTYPE html>
    <html>
      <head>
        ... title and metas
        <%= stylesheet_link_tag 'admin', media: 'all' %>
        <%= javascript_include_tag 'admin' %>
      </head>
      <body>
         ... layout content
      </body>
    <html>
    

    front.html.erb

    <!DOCTYPE html>
    <html>
      <head>
        ... title and metas
        <%= stylesheet_link_tag 'front', media: 'all' %>
        <%= javascript_include_tag 'front' %>
      </head>
      <body>
         ... layout content
      </body>
    <html>
    

    Finally, you must add your manifest files in config/initializers/assets.rb to be precompiled:

    ... some code
    Rails.application.config.assets.precompile += %w(admin.scss front.scss)
    Rails.application.config.assets.precompile += %w(admin.js front.js)
    

    Now you only need to use the desired layout (admin.html.erb or front.html.erb) when rendering your views.