Rails Spree 插件开发总结之八个步骤细节

TCnet · 2020年04月20日 · 最后由 sitoto 回复于 2020年05月12日 · 4647 次阅读

用 spree 做电商网站的朋友,会想修改程序来满足自己的需求。当然可以直接下载程序修改,最好的方式是写一个插件来添加和修改自己需要的功能。

开始写插件会有很多的问题,我这里把我开发的一个插件 spree_mati 的过程详细记录下,希望可以对开始学习的你有点帮助。

插件地址 https://github.com/TCnet/spree_mati

参考资料 spree 官网教程:https://guides.spreecommerce.org/developer/tutorials/extensions_tutorial.html

如何安装插件:https://guides.spreecommerce.org/developer/customization/extensions.html#installing-an-extension

好了 开始我们的插件开发记录:

这里是苹果系统并安装好了开发环境,一些是终端运行细节。

1. 创建插件并打开项目

mkdir my_extension

cd my_extension

spree extension spree_mati

cd spree_mati

#这是 textmate 打开项目命令 如果你用其他的编辑器 不需要运行

subl .
#Gemfile文件添加依赖的gems
gem 'roo','~> 2.8.0'
gem 'roo-xls'
bundle install

2、创建数据库结构和模型 A、创建迁移 迁移文件内容见插件代码 db 文件

在终端执行:

#记录上传的excel表格
bundle exec rails g migration create_spree_mati_import
#添加bullet_point 到产品表格
bundle exec rails g migration add_bullet_point_to_spree_products
#添加standard_price 和 list_price  到产品变体表格
bundle exec rails g migration add_standard_price_to_spree_variants
#添加亚马逊的产品链接,用于引流到亚马逊下单
bundle exec rails g migration add_amazon_link_to_spree_products

B、数据模型

在 app/models/spree/ 下新建 模型文件

mati.rb #空着预留 mati_import.rb

module Spree
  class MatiImport < Spree::Base
     has_one_attached :datafile  #上传文件
  end
end

mati_setting.rb #配置设置文件

module Spree
  class MatiSetting < Spree::Preferences::Configuration 
    preference :import_row_from_title, :integer, default: 3
    preference :ama_title, :string, default: "{0} at Aodrusa {1} Clothing store"
    preference :ama_description, :string , default: "Buy {0} and other {1} at {2}. We Offer New Women's Fashion Clothing Very Frequent"   
  end
end

user_decorator.rb#修改用户 记录属于当前操作用户

module Spree::UserDecorator
  def self.prepended(base)
    base.has_many :mati_imports, class_name: 'Spree::MatiImport'
  end
end
Spree::User.prepend Spree::UserDecorator

3、添加设置路由和本地化文件。 在 config/routes.rb 添加路由

# Add your extension routes here
  namespace :admin do 
    resources :mati_imports do
      member do
        post :importdata
      end
    end 
    get 'mati_settings' => 'mati_settings#edit'
    patch 'mati_settings' => 'mati_settings#update'
  end

本地化文件,config/locales/en.html

添加修改你要用到的文字比如

en:
  spree:
    mati: Mati

在视图文件可以<%= Spree.t('mati') %>来显示 Mati 了

4、添加 override 文件目录和文件用来添加修改 spree 的文件 在 app/overrides/spree/admin 下添加 后台需要添加的文件包括新增菜单导航,修改产品添加页面等。

这边只列举菜单添加菜单代码,因为这个你肯定会用到的

创建 add_mati_to_admin_sidebar.rb 文件

Deface::Override.new(
    virtual_path: 'spree/admin/shared/_main_menu',
    name: 'mati_admin_sidebar_menu',
    insert_top: 'nav',
    partial: 'spree/admin/shared/mati_sidebar_menu'
  )

mati_sidebar_menu 在 app/views/spree/admin/shared/目录下

mati_sidebar_menu.html.erb

<% if can? :admin, Spree::Mati %>
    <ul class="nav nav-sidebar border-bottom">
      <%= main_menu_tree Spree.t(:mati), icon: "leaf", sub_menu: "mati", url: "#sidebar-mati" %>
    </ul>
  <% end %>

然后在 shared/sub_menu/_mati.html.erb

<ul id="sidebar-mati" class="border-top bg-white collapse nav nav-pills nav-stacked" data-hook="admin_mati_sub_tabs">
<%= tab :mati_imports %>
<%= configurations_sidebar_menu_item(Spree.t('mati_settings.title'), admin_mati_settings_path) if can? :manage, Spree::MatiSetting %>
</ul>

这样一个导航菜单就完成了,包含两个导航,一个链接到 imoprts 页面,一个链接到设置页面,这里 Spree::MatiSetting 是第二步里创建的模型

5、添加控制器 controller 我们只有一个导入功能和一个设置,因此只有两个控制器就可以了

分别是 mati_imports_controller.rb 和 mati_settings_controller.rb 具体内容查看我的代码,这边不详细写了。mati_imports_controller 除了 index 方法我们还定义了 importdata 用来导入对应表格的产品数据

6、添加自己的辅助方法 helpers 和服务代码 在 app/helpers/目录下创建 products_helper_decorator.rb

重写了 product_description 方法和添加了 product_bullet_point 方法用来修正前台产品页显示 description 和 bullet_point 方式,可以在 view 页面里直接使用

创建 app/services 文件目录,这个目录下的代码我称为服务代码,可以在控制器里直接使用

我们创建了 albums_service.rb ,color_code.rb,import_service.rb, size_code.rb, template_seed.rb

albums_service.rb 是处理导入文件用到的一些方法,这里都采用类方法的形式,不需要实例化直接使用

比如这个 获取表格标题的方法

def self.get_title_of_template(sheet,slipstr=' ')
  ......
end

这个方法在控制器直接用 AlbumsService.get_title_of_template 就可以调用了。

color_code.rb 是处理颜色的代码,我们约定了颜色的缩写,在我的另一个 erp 系统里,根据图片名称包含的颜色代码缩写,自动生产 sku,和产品颜色的功能,这边引导入产品表格有包含 sku 和颜色,所以暂时没什么用。保留以后可以使用。

import _service.rb 来自 spree 的原版 代码,做些修改,使其可以导入图片和设置库存之类的功能。

size_code.rb 类似 color_code.rb 处理尺码的代码

TemplateSeed 我们定义了一些常量,用来存储亚马逊表格常用字段。这里可以帮它设置到数据库里面比如,在 Spree::MatiSetting 模型 文件里。我们这边没这么做是因为这个基本是固定的,所以我们设置为常量

7、添加修改视图 views 在 app/views/spree/admin/目录下创建

mati_imports 和 mati_setting 文件目录,里面放对应的视图文件

比如 mati_imports 里面有 index.html.erb 和_form.html.erb。mati_setting 里有 edit.html.erb 文件。

在 app/veiws/spree/products/ 目录下添加产品展示页面新增的两个字段 amazon_link 和 bullet_point

我们来看下具体怎么写。比如_amazon_link.html.erb

<% if !@product.amazon_link.blank? %>
<div id="amazon-link" class="mt-2"  data-hook="amazon-link">
  <div>
  <%= link_to @product.amazon_link , class: 'btn btn-warning btn-block' do %>
  <%=@product.amazon_title%> Now!
  <% end %>
</div>
</div>
<% end %>

上面我们提到的第 4 步,override 文件下我们创建了

add_amazon_link_to_product_show.rb 就是用来调用这个 view 文件的具体看 里面的内容

app/overrides/spree/admin/add_amazon_link_to_product_show.rb

Deface::Override.new(
    virtual_path: 'spree/products/show',
    name: 'Add amazon links to show',
    insert_after: 'div[data-hook="cart_form"]',
    partial: 'spree/products/amazon_link'
)

非常简单

8、修改引擎文件,设置配置启动文件和版本的控制 lib/spree_mati/engine.rb 就是引擎文件默认不需修改,我们这边要让程序载入配置文件,因此我们增加了下面代码;

initializer 'spree.mati.environment', before: :load_config_initializers do |_app|
        Spree::MatiConfig = Spree::MatiSetting.new
    end

这样可以直接在控制器,视图等地方直接使用 Spree::MatiConfig 来获取配置字段。比如

Spree::MatiConfig.import_row_from_title 就可以获取我们的设置字段了。

版本控制,你做一次修改后,在版本文件 lib/spree_mati/version.rb 修改版本数字,一般是小修改,比如 TINY = 1 这里改为 2 就好了,每次加 1 就好了。具体看你喜欢但是一定要重小到大。

因为项目比较简单,我并没有写测试,测试可以在写控制器 辅助方法和 views 的时候逐步完成。

最后在主程序安装我们插件的时候别忘了加入

gem 'roo','~> 2.8.0'
gem 'roo-xls'

不然会无法调用 roo 的。

这里是你使用 spree 时要添加的 gem:

gem 'spree', '~> 4.1'
gem 'spree_auth_devise', '~> 4.1'
gem 'spree_gateway', '~> 3.7'
gem 'spree_mati', github: 'TCnet/spree_mati'
gem 'roo','~> 2.8.0'
gem 'roo-xls'

以上 8 个步骤是我总结的 spree 插件开发的过程。

可以帮助初学者尽快写出一个自己的 spree 插件。

国内不流行用这个

需要 登录 后方可回复, 如果你还没有账号请 注册新账号