In this post, we will see how we can customize our spree store.

Click on the link below to set up Spree store on a windows machine

Setting up Spree on a Windows machine

First of all, we need to know following:

  1. Spree files are not part of your project
  2. The page that displays products, checkout etc. is called spree front-end where as admin part is called spree back-end
  3. The spree files are generally located in the gems folder of Ruby. In our case, our front-end files are located at following path:
    C:\RailsInstaller\Ruby2.1.0\lib\ruby\gems\2.1.0\gems\spree_frontend-3.0.4

    Remember this path for now.

  4. To change front-end features of our store, we can override existing files from the above path.
Overriding CSS

Let us first run our store. Go into your project directory and execute the command:

rails server

Open the following link in the browser:

http://localhost:3000

Now, create a new file named custom.css in the following location in your project:

\vendor\assets\stylesheets\spree\frontend\custom.css

We will use this file to override existing styles.

If you are using Google Chrome or Firefox, right click on the product footer and click inspect element. On the right hand side, you can see the css styles. Copy the following class:

.panel-footer {
    padding: 10px 15px;
    background-color: whitesmoke;
    border-top: 1px solid #dddddd;
    border-bottom-right-radius: 3px;
    border-bottom-left-radius: 3px;
}

Now change the background-color value and refresh your page.

Bingo! You have just overridden existing css style from spree in your custom css file.

Any css file that is added to the frontend folder will be automatically loaded at frontend of the website. This is because there is a line:

*= require_tree .

in the all.css file. To understand more about this, you need to read how rails manages asset pipeline.

Overriding existing templates

Now, we will override existing views from spree frontend.

To override an existing template (view file), we need to put our file in the same directory structure as the original one.

Let us suppose we want to remove the left part of the home page that displays Shop by.
spree-home-page-categories

First of all open the following file in your favorite editor ( I prefer RubyMine ):

C:\RailsInstaller\Ruby2.1.0\lib\ruby\gems\2.1.0\gems\spree_frontend-3.0.4\app\views\spree\home

Above path could be different for you as you might have installed RailsInstaller somewhere else.
Next create the following directory structure in your project folder:

app\views\spree\home

Now copy the file index.html.erb from spree_frontend_3.0.4 to our spree\home folder. The content in the file looks like this:

<% content_for :sidebar do %>
  <div data-hook="homepage_sidebar_navigation">
    <%= render :partial => 'spree/shared/taxonomies' %>
  </div>
<% end %>

<div data-hook="homepage_products">
  <% cache(cache_key_for_products) do %>
    <%= render :partial => 'spree/shared/products', :locals => { :products => @products } %>
  <% end %>
</div>

To remove Shop By section, we can simply remove the part:

<% content_for :sidebar do %>
  <div data-hook="homepage_sidebar_navigation">
    <%= render :partial => 'spree/shared/taxonomies' %>
  </div>
<% end %>

Save the file and refresh the page.

Overriding existing controller actions

To override actions of existing controllers, we can create our own decorators. Decorators are used to extend or override actions of existing controllers.

The name of decorator files depends on controller file name. For example, if we have a controller file named:

test_controller.rb

then decorator file name would be:

test_controller_decorator.rb

So, if we have following controller from Spree:

\app\controllers\spree\products_controller.rb

we can create following decorator in our project:

\app\controllers\spree\products_controller_decorator.rb

Now, we add following code:

module Spree
  Spree::ProductsController.class_eval do

     # copy and paste existing actions here and customize

  end
end
Adding new actions to existing controllers

To add new methods, we can again use decorators. For example, if we want to add a new action named cart that returns current cart as json, we can create following decorator in our project:

\app\controllers\spree\orders_controller_decorator.rb

with following code:

module Spree
  Spree::OrdersController.class_eval do
     def cart
       order = current_order()
       render :json => {'message' => 'cart', 'cart' => create_cart(order.line_items)}
     end
  end
end

Now add following route in the config\routes.rb file:

Spree::Core::Engine.routes.draw do
  get 'get-cart' => 'orders#cart'
end

Now, you can get the cart whenever you execute the URL:

http://localhost:3000/get-cart