SpreeCommerce Customizations

The SpreeCommerce Guide lists a few methods to customize SpreeCommerce as per your usage. Here, we’ll be expanding on it further. How to customize various parts of your SpreeCommerce apps.

Assets:

Sometimes we need to customize the way Spree javascript works or need to change the css from the one that came with Spree. One way to go about it is to add a new file under app/assets and update all the required code. This works well when only specific parts of the code in a file need to be overwritten or new code needs to be added. But to override complete files, this takes up more code than needed.

Spree File at app/assets/javascripts/spree/backend/line_items_on_order_edit.js:

$(document).ready(function() {
  'use strict';
  // handle variant selection, show stock level.
  $('#add_line_item_variant_id').change(function() {
    // some JS code
  });
});

addVariant = function() {
  // some JS code
}

adjustLineItems = function(order_number, variant_id, quantity) {
  // some JS code
}

To update the addVariant method in the above Spree js file, you can create a new file in your project with the following code and then require it as needed.

Project File at app/assets/javascripts/spree/backend/update_line_items_on_order.js:

addVariant = function() {
  // some updated JS code
}

This works great when the code that needs change is limited. But when the whole file needs to be changed, a better way to do this would be adding a new file in vendor/assets at the same relative location as the library file uses the code from the new file instead of the library one. This replaces the whole library file. All code needs to be rewritten in this case, even the part not being changed.

To update the file, you can create a new file in your project with the following code under vendor/assets. Since you’re replacing the Spree file with yours, you’ll not need to require this file again. Wherever the Spree file is added, this will replace its code with it.

Project File at vendor/assets/javascripts/spree/backend/line_items_on_order_edit.js:

$(document).ready(function () {
  'use strict';
  // handle variant selection, show stock level.
  $('#add_line_item_variant_id').change(function(){
    // some JS code
  });
});

/* addVariant code is updated */
addVariant = function() {
  // updated JS code
}

// function adjustLineItems is removed as it is not rewritten

/* lineItemsAdjust method is added */
var lineItemsAdjust = function() {
  // new JS code
}

The code written in the original Spree file will not be used. In case you need to use the original code, you’ll need to add it manually by copying it into your project file.

Spree Classes:

Spree classes(Models, controllers, etc.) can be overwritten by writing a decorator at the required location. So if I want to overwrite code for Spree::Product, I need to create a file in my project folder at app/models/spree/product_decorator.rb.

Spree file at app/models/spree/product.rb:

module Spree
  class Product < Spree::Base
    # some code

    def available?
      !(available_on.nil? || available_on.future?) && !deleted? && !discontinued?
    end

    # some other code
  end
end

Project file at app/models/spree/product_decorator.rb:

Spree::Product.class_eval do
  def available?
    can_supply?
  end

  def has_options?
    option_types.any?
  end
end

This will update the code in the available? method and another method called has_options? will be added to the Spree::Product class. The code in the remaining methods will remain same as in the Spree product.rb file.

While this method is perfectly fine when completely overwriting methods, if one needs to add to the code of an existing method, one needs to prepend a module to the class so that the existing method can also be used.

Project file at app/models/spree/product_decorator.rb:

Spree::Product.class_eval do
  prepend Spree::ProductAvailable

  def has_options?
    option_types.any?
  end
end

Project file at app/models/concerns/spree/product_available.rb:

module Spree
  module ProductAvailable
    def available?
      super && can_supply?
    end
  end
end

This will add code on top of already existing code in available? method from the Spree product.rb file.

PermittedAttributes :

A simple way to override permitted attributes is by overwriting them in the initializer config/initializers/spree.rb:

Project File at config/initializers/spree.rb:

Spree::PermittedAttributes.user_attributes.push(:middle_name)

While this version works fine, but working on it in development mode causes you to restart the server each time you need to add another attribute to the permitted list. A better way is to create a decorator for Spree::PermittedAttributes.

PROJECT file at lib/spree/permitted_attributes_decorator.rb:

Spree::PermittedAttributes.user_attributes.push(:middle_name)
Tagged as:

One thought on “SpreeCommerce Customizations

  1. Pingback: SpreeCommerce Customizations | Vinsol | Spree C...

Leave a Reply

Your email address will not be published. Required fields are marked *