Migrating a Shopify Help Center script template
Every example script Shopify published shared one skeleton: a settings constant the merchant edited, a banner comment, then class code nobody was meant to touch. If your file opens with a row of equals signs, this is the dialect you have.
可重建It read the merchant-edited constant at the top of the file and applied that discount to every matching line.
商家用 2 种不同写法写过这段逻辑,它们的含义并不相同。每种写法都列在下方,各自配有对应的购物车和数字。
把它粘贴到 Scripts 救援,看看会重建成什么
- 用本页任意 Script 旁边的按钮复制 Ruby 代码。
- 在 Shopify 后台打开 Stackable,依次进入工具、Scripts 救援。
- 粘贴进去,读一读工具说它会创建什么,再和本页的设置逐项对照。
Scripts 救援属于 Pro 套餐。在您填写旧 Script 的折扣金额、且两个数字精确到最小货币单位完全一致之前,不会发布任何内容。
Official dialect, tiered spend
可重建# ================================ Customizable Settings ================================
# ================================================================
# Tiered Discount by Spend
#
# If the cart total is greater than (or equal to) an entered
# threshold, the associated discount is applied to each item.
# ================================================================
SPENDING_THRESHOLDS = [
{
threshold: 30,
discount_type: :percent,
discount_amount: 10,
discount_message: '10% off for spending over $30',
},
{
threshold: 60,
discount_type: :percent,
discount_amount: 15,
discount_message: '15% off for spending over $60',
},
]
# ================================ Script Code (do not edit) ================================
class DiscountApplicator
def initialize(discount_type, discount_amount, discount_message)
@discount_type = discount_type
@discount_message = discount_message
@discount_amount = if discount_type == :percent
1 - (discount_amount * 0.01)
else
Money.new(cents: 100) * discount_amount
end
end
def apply(line_item)
new_line_price = if @discount_type == :percent
line_item.line_price * @discount_amount
else
[line_item.line_price - (@discount_amount * line_item.quantity), Money.zero].max
end
line_item.change_line_price(new_line_price, message: @discount_message)
end
end
class TieredDiscountBySpendCampaign
def initialize(campaigns)
@campaigns = campaigns
end
def run(cart)
applicable_campaign = nil
@campaigns.each do |campaign|
threshold = Money.new(cents: 100) * campaign[:threshold]
applicable_campaign = campaign if cart.subtotal_price >= threshold
end
return if applicable_campaign.nil?
discount_applicator = DiscountApplicator.new(
applicable_campaign[:discount_type],
applicable_campaign[:discount_amount],
applicable_campaign[:discount_message],
)
cart.line_items.each do |line_item|
discount_applicator.apply(line_item)
end
end
end
CAMPAIGNS = [
TieredDiscountBySpendCampaign.new(SPENDING_THRESHOLDS),
]
CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end
Output.cart = Input.cart识别为 Spend threshold discount,重建为 spend_goal 类型的优惠。下面是优惠实际保存时使用的配置键,您可以逐项核对自己的重建结果。
| 设置项 | 值 | 配置键 |
|---|---|---|
| Offer type | spend_goal | type |
| Counting | per_cart | counting |
| Recurrence | once | recurrence |
| Tier 1 | min spend $30.00 -> 10% off | tiers[0] |
| Tier 2 | min spend $60.00 -> 15% off | tiers[1] |
| Target scope | all | target.scope |
| Method | automatic | discountMethod |
| Allocation | standard | stacking.allocation |
| Combines with other discounts | no | stacking |
- Confirm which products this applies to. We could not read product targeting from the script.
基于我们的公开演示店铺 Meridian Goods 搭建,因此这里的每个价格都可以复现,而不必凭信任接受。下方的折扣金额,是结账时运行的同一个引擎针对这个购物车算出的结果。
| 商品 | 数量 | 单价 |
|---|---|---|
| Softcover Notebook Set | 1 | $18.00 |
| Braided USB-C Cable | 1 | $14.00 |
| 小计 | $32.00 | |
| 折扣 | -$3.20 | |
| 总额 | $28.80 | |
未登录,或以没有标签的客户身份登录。
发布之前,工具会询问您原来的 Script 对一个现有购物车做了什么。把它设为 2 件 Softcover Notebook Set,单价 $18.00,答案就是固定的。
折扣金额为 $3.60。顾客实际支付的总额为 $32.40。
比对精确到您所用货币的最小单位。差一分钱,发布就仍然被拦住,这正是这一步的意义。
- swap the cart for a single Braided USB-C Cable
| 商品 | 数量 | 单价 |
|---|---|---|
| Braided USB-C Cable | 1 | $14.00 |
| 小计 | $14.00 | |
| 总额 | $14.00 | |
未登录,或以没有标签的客户身份登录。
Official dialect, lineitem applicator (D16)
可重建危险配对 D16。这个文件和它的搭档看起来几乎一样,行为却不同,在判断您手上是哪一个之前,请把两份都读一遍。
# ================================ Customizable Settings ================================
DISCOUNT_TYPE = :percent
DISCOUNT_AMOUNT = 10
DISCOUNT_MESSAGE = '10% off everything'
# ================================ Script Code (do not edit) ================================
class DiscountApplicator
def initialize(discount_type, discount_amount, discount_message)
@discount_type = discount_type
@discount_message = discount_message
@discount_amount = if discount_type == :percent
1 - (discount_amount * 0.01)
else
Money.new(cents: 100) * discount_amount
end
end
def apply(line_item)
new_line_price = if @discount_type == :percent
line_item.line_price * @discount_amount
else
[line_item.line_price - (@discount_amount * line_item.quantity), Money.zero].max
end
line_item.change_line_price(new_line_price, message: @discount_message)
end
end
class ProductDiscountCampaign
def initialize(discount_applicator)
@discount_applicator = discount_applicator
end
def run(cart)
cart.line_items.each do |line_item|
@discount_applicator.apply(line_item)
end
end
end
CAMPAIGNS = [
ProductDiscountCampaign.new(
DiscountApplicator.new(DISCOUNT_TYPE, DISCOUNT_AMOUNT, DISCOUNT_MESSAGE),
),
]
CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end
Output.cart = Input.cart识别为 Percentage off,重建为 volume 类型的优惠。下面是优惠实际保存时使用的配置键,您可以逐项核对自己的重建结果。
| 设置项 | 值 | 配置键 |
|---|---|---|
| Offer type | volume | type |
| Counting | per_product | counting |
| Recurrence | once | recurrence |
| Tier 1 | min qty 1 -> 10% off | tiers[0] |
| Target scope | all | target.scope |
| Method | automatic | discountMethod |
| Allocation | standard | stacking.allocation |
| Combines with other discounts | no | stacking |
- Confirm which products this applies to. We could not read product targeting from the script.
基于我们的公开演示店铺 Meridian Goods 搭建,因此这里的每个价格都可以复现,而不必凭信任接受。下方的折扣金额,是结账时运行的同一个引擎针对这个购物车算出的结果。
| 商品 | 数量 | 单价 |
|---|---|---|
| Braided USB-C Cable | 1 | $14.00 |
| 小计 | $14.00 | |
| 折扣 | -$1.40 | |
| 总额 | $12.60 | |
未登录,或以没有标签的客户身份登录。
发布之前,工具会询问您原来的 Script 对一个现有购物车做了什么。把它设为 1 件 Braided USB-C Cable,单价 $14.00,答案就是固定的。
折扣金额为 $1.40。顾客实际支付的总额为 $12.60。
比对精确到您所用货币的最小单位。差一分钱,发布就仍然被拦住,这正是这一步的意义。
This rule carries no condition at all, so it fires on any cart holding anything and there is no quiet cart to build. The negative check is an empty cart, which the app runs for you. That is correct behaviour, not a failure.
两个看起来一样的文件
下面每一对都是同一种 Script 写法的两个版本。它们只差一两行,效果却不同,所以在判断自己手上是哪一个之前,请把两个都读一遍。
危险配对 D16
Official dialect, lineitem applicator (D16)
可重建重建为 volume 优惠。
在它自己的购物车中的折扣:$1.40
DISCOUNT_MESSAGE = '10% off everything'
1 - (discount_amount * 0.01)
def apply(line_item)
new_line_price = if @discount_type == :percent
line_item.line_price * @discount_amount
[line_item.line_price - (@discount_amount * line_item.quantity), Money.zero].max另有 8 行差异,在它自己的页面上。
Official dialect, shipping applicator (D16)
可重建重建为 free_shipping 优惠。
在它自己的购物车中的运费节省:$0.69
DISCOUNT_MESSAGE = '10% off shipping'
discount_amount * 0.01
def apply(shipping_rate)
discount_amount = if @discount_type == :percent
shipping_rate.price * @discount_amount
@discount_amount > shipping_rate.price ? shipping_rate.price : @discount_amount另有 8 行差异,在它自己的页面上。
常见问题
- Will Stackable rebuild this script?
- Yes. Every spelling on this page is rebuilt today as a spend_goal offer, and the cart above is the one that proves it.
- What cart proves it works?
- 1 x Softcover Notebook Set at $18.00 plus 1 x Braided USB-C Cable at $14.00. The engine takes $3.20 off, and checkout charges $28.80.
- What will I have to check before publishing?
- Confirm which products this applies to. We could not read product targeting from the script.
相关的 Script 类型
A share taken off every delivery rate at checkout.
Generator output, with a CAMPAIGNS array at the bottom that states the merchant’s intent as data.