spree_address_format_i18n 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +1 -0
- data/Gemfile +3 -0
- data/LICENSE +673 -0
- data/README.md +58 -0
- data/app/.gitkeep +0 -0
- data/app/controllers/.gitkeep +0 -0
- data/app/helpers/spree/addresses_helper_decorator.rb +47 -0
- data/app/helpers/spree/admin/base_helper_decorator.rb +16 -0
- data/app/models/.gitkeep +0 -0
- data/app/models/spree/user_decorator.rb +40 -0
- data/app/models/spree_address_format_i18n/address_decorator.rb +145 -0
- data/app/models/spree_address_format_i18n/permitted_attributes_decorator.rb +9 -0
- data/app/models/spree_address_format_i18n/store_decorator.rb +14 -0
- data/app/overrides/spree/account/profile/edit/reorder_position_fields.html.erb.deface +39 -0
- data/app/overrides/spree/admin/shared/_address/reorder_address_fields.html.erb.deface +6 -0
- data/app/overrides/spree/admin/stores/add_country_field_settings.rb +6 -0
- data/app/overrides/spree/remove_address_phone.rb +13 -0
- data/app/overrides/spree/replace_ship_address_format.rb +6 -0
- data/app/overrides/spree/shared/_address/reorder_address_fields.html.erb.deface +6 -0
- data/app/serializers/.gitkeep +0 -0
- data/app/services/.gitkeep +0 -0
- data/app/views/spree/address_format/_address_field.html.erb +20 -0
- data/app/views/spree/address_format/_address_group.html.erb +13 -0
- data/app/views/spree/addresses/_form.html.erb +55 -0
- data/app/views/spree/admin/shared/_address_form.html.erb +45 -0
- data/app/views/spree/admin/stores/_country_field_settings.html.erb +9 -0
- data/bin/rails +8 -0
- data/config/initializers/spree_permitted_attributes.rb +10 -0
- data/config/locales/en.yml +6 -0
- data/config/locales/ja.yml +27 -0
- data/config/locales/order.ja.yml +48 -0
- data/db/migrate/20241231080436_add_kana_columns_to_users.rb +6 -0
- data/db/migrate/20250428020947_change_value_country.rb +11 -0
- data/db/migrate/20250505070307_add_company_kana_and_fax_to_spree_addresses.rb +6 -0
- data/lib/generators/spree_address_format_i18n/add_kana_fields_generator.rb +20 -0
- data/lib/generators/spree_address_format_i18n/install/install_generator.rb +20 -0
- data/lib/generators/spree_address_format_i18n/install_generator.rb +13 -0
- data/lib/generators/spree_address_format_i18n/templates/initializer.rb +8 -0
- data/lib/spree_address_format_i18n/configuration.rb +9 -0
- data/lib/spree_address_format_i18n/engine.rb +32 -0
- data/lib/spree_address_format_i18n/factories.rb +6 -0
- data/lib/spree_address_format_i18n/version.rb +7 -0
- data/lib/spree_address_format_i18n.rb +21 -0
- data/spree_address_format_i18n.gemspec +34 -0
- metadata +200 -0
data/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
SpreeAddressFormatI18n
|
|
2
|
+
=====================
|
|
3
|
+
|
|
4
|
+
This extension provides:
|
|
5
|
+
1. Customizable address field ordering through YAML configuration
|
|
6
|
+
2. Japanese kana field support for addresses (firstname_kana, lastname_kana)
|
|
7
|
+
|
|
8
|
+
Install
|
|
9
|
+
=======
|
|
10
|
+
|
|
11
|
+
Add the following line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem "spree_address_format_i18n", :git => "https://github.com/be-agile/spree_address_format_i18n.git", :branch => 'master'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bundle install
|
|
21
|
+
bundle exec rails g spree_address_format_i18n:install
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Configuration
|
|
25
|
+
============
|
|
26
|
+
|
|
27
|
+
To customize the order of address fields, create a YAML file in your application's config/locales directory:
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
# config/locales/order.ja.yml
|
|
31
|
+
ja:
|
|
32
|
+
address_format_i18n:
|
|
33
|
+
- lastname
|
|
34
|
+
- firstname
|
|
35
|
+
- lastname_kana
|
|
36
|
+
- firstname_kana
|
|
37
|
+
- country
|
|
38
|
+
- zipcode
|
|
39
|
+
- state
|
|
40
|
+
- city
|
|
41
|
+
- address1
|
|
42
|
+
- address2
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The extension will use this configuration to determine the order of fields in address forms and displays. Fields not specified in the configuration will be displayed at the end in their default order.
|
|
46
|
+
|
|
47
|
+
Japanese Kana Support
|
|
48
|
+
====================
|
|
49
|
+
|
|
50
|
+
This extension adds support for Japanese kana fields (firstname_kana, lastname_kana) to Spree addresses. These fields are automatically added to the database when you run the migrations.
|
|
51
|
+
|
|
52
|
+
To use the kana fields:
|
|
53
|
+
|
|
54
|
+
1. Make sure you've run the migrations: `bundle exec rails g spree_address_format_i18n:install`
|
|
55
|
+
2. Include the kana fields in your address_format_i18n configuration (see example above)
|
|
56
|
+
3. The kana fields will be displayed in address forms and on address display pages according to your configuration
|
|
57
|
+
|
|
58
|
+
Validation for kana fields ensures that they contain only katakana characters.
|
data/app/.gitkeep
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module AddressesHelperDecorator
|
|
3
|
+
# List of kana fields that should not be excluded even when `store.use_kana_fields` is false.
|
|
4
|
+
IGNORED_KANA_FIELDS = [ :company_kana ]
|
|
5
|
+
|
|
6
|
+
def order_address_fields(store)
|
|
7
|
+
name_order = I18n.t('address_format_i18n.fields')
|
|
8
|
+
return Spree::Address::ADDRESS_FIELDS if name_order.blank?
|
|
9
|
+
|
|
10
|
+
fields = filter_address_fields(Spree::Address::ADDRESS_FIELDS, store)
|
|
11
|
+
|
|
12
|
+
# Filter out kana fields if use_kana_fields is false
|
|
13
|
+
unless store.use_kana_fields
|
|
14
|
+
fields = fields.reject { |field| field.include?('kana') }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
fields.sort_by do |field|
|
|
18
|
+
name_order.index(field) || Float::INFINITY
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def order_address_groups(store)
|
|
23
|
+
groups = I18n.t('address_format_i18n.groups').deep_dup
|
|
24
|
+
unless store.use_kana_fields
|
|
25
|
+
fn_group = groups.find { |group| group[:name] == 'fn' }
|
|
26
|
+
fn_group[:fields] = fn_group[:fields].reject { |field| field.include?('kana') }
|
|
27
|
+
end
|
|
28
|
+
groups
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def order_account_edit
|
|
32
|
+
I18n.t('address_format_i18n.account.profile', default: %w[last_name first_name phone email])
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def filter_address_fields(fields, store)
|
|
38
|
+
return fields if store.use_kana_fields
|
|
39
|
+
|
|
40
|
+
fields.reject do |field|
|
|
41
|
+
field.include?('kana') && !IGNORED_KANA_FIELDS.include?(field.to_sym)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Spree::AddressesHelper.prepend(AddressesHelperDecorator)
|
|
47
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module BaseHelperDecorator
|
|
4
|
+
def order_address_fields(address_fields)
|
|
5
|
+
name_order = I18n.t('address_format_i18n')
|
|
6
|
+
return address_fields if name_order.blank?
|
|
7
|
+
|
|
8
|
+
Spree::Address::ADDRESS_FIELDS.sort_by do |field|
|
|
9
|
+
name_order.index(field) || Float::INFINITY
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Spree::Admin::BaseHelper.prepend(BaseHelperDecorator)
|
|
15
|
+
end
|
|
16
|
+
end
|
data/app/models/.gitkeep
ADDED
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module CustomNameOfPerson
|
|
2
|
+
class PersonName < NameOfPerson::PersonName
|
|
3
|
+
def full
|
|
4
|
+
@full ||= begin
|
|
5
|
+
field_suffixes = I18n.t('address_format_i18n.field_suffixes', default: {})
|
|
6
|
+
suffix = field_suffixes['fn'] || field_suffixes[:fn] || ''
|
|
7
|
+
|
|
8
|
+
order = I18n.t("address_format_i18n.address.full_name", default: %w[first_name last_name])
|
|
9
|
+
parts = order.map do |part|
|
|
10
|
+
case part.to_s.downcase
|
|
11
|
+
when "first_name" then first.to_s.strip
|
|
12
|
+
when "last_name" then last.to_s.strip
|
|
13
|
+
else nil
|
|
14
|
+
end
|
|
15
|
+
end.compact.join(" ").strip
|
|
16
|
+
|
|
17
|
+
base_name = parts.blank? ? first.to_s.strip : parts
|
|
18
|
+
base_name += " #{suffix}" if suffix
|
|
19
|
+
base_name
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# to_sメソッドもオーバーライドして、デフォルトでfullを返すように
|
|
24
|
+
def to_s
|
|
25
|
+
full
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module Spree
|
|
31
|
+
module UserDecorator
|
|
32
|
+
def name
|
|
33
|
+
return nil if first_name.blank?
|
|
34
|
+
|
|
35
|
+
@custom_name ||= CustomNameOfPerson::PersonName.new(first_name.to_s.strip, last_name.to_s.strip)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Spree.user_class.prepend(Spree::UserDecorator)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
module SpreeAddressFormatI18n
|
|
2
|
+
module AddressDecorator
|
|
3
|
+
FIELDS_TO_NORMALIZE = [ "phone", "alternative_phone", "zipcode" ]
|
|
4
|
+
|
|
5
|
+
def self.prepended(base)
|
|
6
|
+
base.before_validation :remove_emoji_and_normalize
|
|
7
|
+
|
|
8
|
+
base.const_set(:ADDRESS_FIELDS, %w[firstname lastname firstname_kana lastname_kana company address1 address2 city state zipcode country phone fax company_kana])
|
|
9
|
+
|
|
10
|
+
# カナ presence は「新規入力」または「このリクエストでカナを変更したとき」のみ要求する。
|
|
11
|
+
# use_kana_fields を後から有効化したストアには、カナ未登録の既存住所が多数存在する
|
|
12
|
+
# (実運用のストアでは3割を超えることもある)。これらは clone_shipping_address で bill=ship として再検証される
|
|
13
|
+
# 際に空のままなので、無条件 presence だと既存ユーザーがチェックアウトできなくなる。
|
|
14
|
+
# 永続済み・未変更の空カナはスキップし、新規 or ユーザーが明示的にカナを変更/クリアした
|
|
15
|
+
# 場合のみ必須にすることで、データ品質(新規は必須)と既存ユーザーの購入可否を両立する。
|
|
16
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1210
|
|
17
|
+
kana_presence_required = lambda do |address, field|
|
|
18
|
+
next false unless Spree::Store.current.use_kana_fields
|
|
19
|
+
address.new_record? || address.public_send(:"#{field}_changed?")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# セイ(lastname_kana)を先に定義してエラーメッセージの順序を制御
|
|
23
|
+
base.validates :lastname_kana, presence: true, if: -> { kana_presence_required.call(self, :lastname_kana) }
|
|
24
|
+
base.validates :lastname_kana, format: { with: /\A[\p{Katakana}\p{Blank}ー・]+\z/, allow_blank: true, message: :invalid_katakana }, if: -> { Spree::Store.current.use_kana_fields }
|
|
25
|
+
|
|
26
|
+
# メイ(firstname_kana)
|
|
27
|
+
base.validates :firstname_kana, presence: true, if: -> { kana_presence_required.call(self, :firstname_kana) }
|
|
28
|
+
base.validates :firstname_kana, format: { with: /\A[\p{Katakana}\p{Blank}ー・]+\z/, allow_blank: true, message: :invalid_katakana }, if: -> { Spree::Store.current.use_kana_fields }
|
|
29
|
+
|
|
30
|
+
base.validates :company_kana, format: { with: /\A[\p{Katakana}\p{Blank}ー・]+\z/ }, if: -> { company_kana.present? }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# @gem-override spree_core-5.3.6/app/models/spree/address.rb#to_s
|
|
35
|
+
# @see https://github.com/be-agile/giga-repeat/commit/c1a9869799d490211889807bc603fe7c94ea66dc
|
|
36
|
+
# 本家の固定フォーマットではなく、i18n の groups 定義に沿った日本語住所表記で組む。
|
|
37
|
+
def to_s
|
|
38
|
+
# texts.reject(&:blank?).join("<br/>").html_safe
|
|
39
|
+
safe_texts = texts.reject(&:blank?).map do |text|
|
|
40
|
+
ERB::Util.html_escape(text.to_s)
|
|
41
|
+
end
|
|
42
|
+
# rubocop:disable Rails/OutputSafety
|
|
43
|
+
safe_texts.join("<br/>").html_safe
|
|
44
|
+
# rubocop:enable Rails/OutputSafety
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def to_text
|
|
48
|
+
texts.reject(&:blank?).join("\n")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def oneline
|
|
52
|
+
texts.join(" ")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def texts
|
|
56
|
+
delimiter = I18n.t("address_format_i18n.delimiter", default: " ")
|
|
57
|
+
groups = I18n.t('address_format_i18n.groups').deep_dup
|
|
58
|
+
field_suffixes = I18n.t('address_format_i18n.field_suffixes', default: {})
|
|
59
|
+
|
|
60
|
+
unless Spree::Store.current.use_kana_fields
|
|
61
|
+
fn_group = groups.find { |group| group[:name] == 'fn' }
|
|
62
|
+
fn_group[:fields] = fn_group[:fields].reject { |field| field.include?('kana') }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
result = groups.flat_map do |group|
|
|
66
|
+
nodes = group[:children] || [ group ]
|
|
67
|
+
|
|
68
|
+
nodes.map do |node|
|
|
69
|
+
# show_country_fieldがfalseの場合、countryフィールドを除外
|
|
70
|
+
visible_fields = node[:fields].dup
|
|
71
|
+
visible_fields.reject! { |field| field.to_s == 'country' } unless Spree::Store.current.show_country_field
|
|
72
|
+
|
|
73
|
+
# 名前グループの特別処理(カナがある場合)
|
|
74
|
+
if group[:name] == 'fn' && Spree::Store.current.use_kana_fields
|
|
75
|
+
line = format_name_with_kana(visible_fields, delimiter)
|
|
76
|
+
else
|
|
77
|
+
field_values = visible_fields.filter_map { |field| respond_to?(field) ? send(field) : nil }
|
|
78
|
+
line = field_values.join(delimiter) if field_values.present?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
if line.present?
|
|
82
|
+
# グループに接尾辞が設定されている場合は追加
|
|
83
|
+
suffix = field_suffixes[group[:name].to_sym] || field_suffixes[group[:name]]
|
|
84
|
+
line += " #{suffix}" if suffix
|
|
85
|
+
line
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @gem-override spree_core-5.3.6/app/models/spree/address.rb#full_name
|
|
92
|
+
# @see https://github.com/be-agile/giga-repeat/commit/c1a9869799d490211889807bc603fe7c94ea66dc
|
|
93
|
+
# 本家 `"#{firstname} #{lastname}"` ではなく、i18n の名前順・接尾辞(様 等)を反映する。
|
|
94
|
+
def full_name
|
|
95
|
+
field_suffixes = I18n.t('address_format_i18n.field_suffixes', default: {})
|
|
96
|
+
|
|
97
|
+
name = I18n.t("address_format_i18n.address.full_name", default: [ "firstname", "lastname" ])
|
|
98
|
+
.map { |part| send(part) if respond_to?(part) }
|
|
99
|
+
.compact.join(" ").strip
|
|
100
|
+
|
|
101
|
+
# fnグループの接尾辞があれば追加
|
|
102
|
+
suffix = field_suffixes['fn'] || field_suffixes[:fn]
|
|
103
|
+
name += " #{suffix}" if suffix && name.present?
|
|
104
|
+
|
|
105
|
+
name
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
def remove_emoji_and_normalize
|
|
111
|
+
attributes_to_normalize = attributes.slice(*FIELDS_TO_NORMALIZE)
|
|
112
|
+
normalized_attributes = attributes_to_normalize.compact_blank.deep_transform_values do |value|
|
|
113
|
+
NormalizeString.remove_emoji_and_normalize(value.to_s).strip
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
normalized_attributes.transform_keys! { |key| key.gsub('original_', '') } if defined?(Spree::Security::Addresses)
|
|
117
|
+
|
|
118
|
+
assign_attributes(normalized_attributes)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def format_name_with_kana(fields, delimiter)
|
|
122
|
+
# 漢字とカナのフィールドを分離
|
|
123
|
+
kanji_fields = fields.reject { |field| field.include?('kana') }
|
|
124
|
+
kana_fields = fields.select { |field| field.include?('kana') }
|
|
125
|
+
|
|
126
|
+
# 漢字名を取得
|
|
127
|
+
kanji_values = kanji_fields.filter_map { |field| respond_to?(field) ? send(field) : nil }
|
|
128
|
+
return nil if kanji_values.blank?
|
|
129
|
+
|
|
130
|
+
kanji_name = kanji_values.join(delimiter)
|
|
131
|
+
|
|
132
|
+
# カナ名を取得(両方空でない場合のみ)
|
|
133
|
+
kana_values = kana_fields.filter_map { |field| respond_to?(field) ? send(field) : nil }
|
|
134
|
+
|
|
135
|
+
if kana_values.present? && kana_values.any?(&:present?)
|
|
136
|
+
kana_name = kana_values.join('') # カナはスペースなしで連結
|
|
137
|
+
"#{kanji_name}(#{kana_name})"
|
|
138
|
+
else
|
|
139
|
+
kanji_name
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
Spree::Address.prepend(SpreeAddressFormatI18n::AddressDecorator)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module SpreeAddressFormatI18n
|
|
2
|
+
module PermittedAttributesDecorator
|
|
3
|
+
def self.prepended(base)
|
|
4
|
+
base.address_attributes.push(:firstname_kana, :lastname_kana, :company_kana, :fax)
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
Spree::PermittedAttributes.prepend(SpreeAddressFormatI18n::PermittedAttributesDecorator)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'active_record/typed_store'
|
|
2
|
+
|
|
3
|
+
module SpreeAddressFormatI18n
|
|
4
|
+
module StoreDecorator
|
|
5
|
+
def self.prepended(base)
|
|
6
|
+
base.typed_store :settings, coder: ActiveRecord::TypedStore::IdentityCoder do |s|
|
|
7
|
+
s.boolean :use_kana_fields, default: false, null: false
|
|
8
|
+
s.boolean :show_country_field, default: false, null: false
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Spree::Store.prepend SpreeAddressFormatI18n::StoreDecorator
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!-- replace_contents 'div.page-container' -->
|
|
2
|
+
<div class="lg:col-span-3">
|
|
3
|
+
<%= render 'spree/account/account_nav', current: 'account' %>
|
|
4
|
+
</div>
|
|
5
|
+
<div class="lg:col-span-8 lg:col-start-5 pb-6">
|
|
6
|
+
<h5 class="uppercase font-medium mb-4"><%= Spree.t('storefront.account.personal_details') %></h5>
|
|
7
|
+
<div class="flex justify-between">
|
|
8
|
+
<p class="mb-3 text-neutral-600">
|
|
9
|
+
<%= Spree.t('storefront.account.please_update_your_contact_details') %>
|
|
10
|
+
</p>
|
|
11
|
+
<% if defined?(spree_edit_password_path) %>
|
|
12
|
+
<%= link_to Spree.t('storefront.account.change_password'), spree_edit_password_path %>
|
|
13
|
+
<% end %>
|
|
14
|
+
</div>
|
|
15
|
+
<%= render partial: 'spree/shared/error_messages', locals: { target: @user } %>
|
|
16
|
+
<%= form_for @user, url: spree.account_profile_path, html: {class: "flex flex-col gap-4"}, method: :put do |f| %>
|
|
17
|
+
<% order_account_edit.each do |field| %>
|
|
18
|
+
<div>
|
|
19
|
+
<% if field == "first_name" %>
|
|
20
|
+
<%= f.label :first_name, Spree.t(:first_name), class: 'text-xs text-neutral-600 block mb-2' %>
|
|
21
|
+
<%= f.text_field :first_name, class: 'text-input w-full', placeholder: Spree.t(:first_name), required: true %>
|
|
22
|
+
<% end %>
|
|
23
|
+
<% if field == "last_name" %>
|
|
24
|
+
<%= f.label :last_name, Spree.t(:last_name), class: 'text-xs text-neutral-600 block mb-2' %>
|
|
25
|
+
<%= f.text_field :last_name, class: 'text-input w-full', placeholder: Spree.t(:last_name), required: true %>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% if field == "phone" %>
|
|
28
|
+
<%= f.label :phone, Spree.t(:phone), class: 'text-xs text-neutral-600 block mb-2' %>
|
|
29
|
+
<%= f.telephone_field :phone, class: 'text-input w-full', placeholder: Spree.t(:phone) %>
|
|
30
|
+
<% end %>
|
|
31
|
+
<% if field == "email" %>
|
|
32
|
+
<%= f.label :email, Spree.t(:email), class: 'text-xs text-neutral-600 block mb-2' %>
|
|
33
|
+
<%= f.text_field :email, class: 'text-input w-full', placeholder: Spree.t(:email), required: true %>
|
|
34
|
+
<% end %>
|
|
35
|
+
</div>
|
|
36
|
+
<% end %>
|
|
37
|
+
<%= f.submit Spree.t(:update), class: 'btn-primary w-full mb-6' %>
|
|
38
|
+
<% end %>
|
|
39
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Deface::Override.new(
|
|
2
|
+
virtual_path: "spree/checkout/complete",
|
|
3
|
+
name: "remove_ship_address_phone",
|
|
4
|
+
remove: "erb[loud]:contains('@order.ship_address.phone')",
|
|
5
|
+
original: "<%= @order.ship_address.phone %>"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
Deface::Override.new(
|
|
9
|
+
virtual_path: "spree/checkout/complete",
|
|
10
|
+
name: "remove_bill_address_phone",
|
|
11
|
+
remove: "erb[loud]:contains('@order.bill_address.phone')",
|
|
12
|
+
original: "<%= @order.bill_address.phone %>"
|
|
13
|
+
)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Deface::Override.new(
|
|
2
|
+
virtual_path: 'spree/checkout/edit',
|
|
3
|
+
name: 'replace_ship_address_format',
|
|
4
|
+
replace: "erb[loud]:contains('@order.ship_address.to_s.gsub')",
|
|
5
|
+
text: "<%= @order.ship_address.to_s.gsub('<br/>', I18n.t('address_format_i18n.delimiter', default: ' ')).html_safe %>"
|
|
6
|
+
)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<% case field %>
|
|
2
|
+
<% when 'firstname', 'lastname', 'firstname_kana', 'lastname_kana' %>
|
|
3
|
+
<%= address.send(field) %>
|
|
4
|
+
<% when 'company' %>
|
|
5
|
+
<%= address.company %>
|
|
6
|
+
<% when 'address1', 'address2' %>
|
|
7
|
+
<div class="street-address-line">
|
|
8
|
+
<%= address.send(field) %>
|
|
9
|
+
</div>
|
|
10
|
+
<% when 'city' %>
|
|
11
|
+
<span class="locality"><%= address.city %></span>
|
|
12
|
+
<% when 'state' %>
|
|
13
|
+
<span class="region"><%= address.state_text %></span>
|
|
14
|
+
<% when 'zipcode' %>
|
|
15
|
+
<span class="postal-code"><%= address.zipcode %></span>
|
|
16
|
+
<% when 'country' %>
|
|
17
|
+
<%= address.country.try(:name) %>
|
|
18
|
+
<% else %>
|
|
19
|
+
<%= address.send(field) if address.respond_to?(field) %>
|
|
20
|
+
<% end %>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<div class="<%= group[:name] %>">
|
|
2
|
+
<% if group[:fields].present? %>
|
|
3
|
+
<% group[:fields].each do |field| %>
|
|
4
|
+
<%= render partial: 'spree/address_format/address_field', locals: { field: field, address: address } %>
|
|
5
|
+
<% end %>
|
|
6
|
+
<% end %>
|
|
7
|
+
|
|
8
|
+
<% if group[:children].present? %>
|
|
9
|
+
<% group[:children].each do |child_group| %>
|
|
10
|
+
<%= render partial: 'spree/address_format/address_group', locals: { group: child_group, address: address } %>
|
|
11
|
+
<% end %>
|
|
12
|
+
<% end %>
|
|
13
|
+
</div>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<%# @gem-override spree_core-5.3.6/app/views/spree/addresses/_form.html.erb %>
|
|
2
|
+
<%# reason: 住所フォームを order_address_fields の可変フィールド方式に置き換え、国フィールド非表示や必須マーカー表示を追加している %>
|
|
3
|
+
<%# Spree 5.3 追従: countries/states の data 属性を address_form_countries_states_cache_key で cache 化 %>
|
|
4
|
+
<%# @see https://github.com/be-agile/giga-repeat/commit/42492d8a839026e80c486d1e4f1621d16b5ae02f %>
|
|
5
|
+
<% address ||= address_form.object %>
|
|
6
|
+
<% address_id = address_type.chars.first %>
|
|
7
|
+
|
|
8
|
+
<%# address-autocomplete (Spree 5.3コアのGoogle Places補完) は外す。本フォームは
|
|
9
|
+
可変フィールド方式で address1 等のコア必須ターゲットを持たないため、付けたままだと
|
|
10
|
+
コントローラが Missing target "address1" で disconnect 時に JSエラーを出す。 %>
|
|
11
|
+
<div class="inner"
|
|
12
|
+
data-controller="address-form"
|
|
13
|
+
<% cache address_form_countries_states_cache_key do %>
|
|
14
|
+
data-address-form-countries-value="<%= available_countries.to_json %>"
|
|
15
|
+
data-address-form-states-value="<%= available_states.to_json %>"
|
|
16
|
+
<% end %>
|
|
17
|
+
data-address-form-current-state-id-value="<%= address.state_id %>">
|
|
18
|
+
|
|
19
|
+
<% order_address_fields(current_store).each do |field| %>
|
|
20
|
+
<% if field == "country" %>
|
|
21
|
+
<%# 国フィールドをdisplay:noneで非表示にする(show_country_fieldがfalseの場合) %>
|
|
22
|
+
<div id="<%= "#{address_id}country" %>" <%= ('style="display:none;"'.html_safe) unless current_store.show_country_field %>>
|
|
23
|
+
<div class="form-group mb-0">
|
|
24
|
+
<div id="<%= "#{address_id}country-selection" %>">
|
|
25
|
+
<%= address_form.label(Spree.t(:country), Spree.t(:country), class: 'block text-xs text-neutral-600 mb-1') %>
|
|
26
|
+
<%= address_form.select :country_id, options_for_select(available_countries.map { |c| [c.name, c.id, data: { iso: c.iso }] }, address_form.object.country_id || current_store.default_country_id),
|
|
27
|
+
{ },
|
|
28
|
+
{ class: 'w-full select-input mb-4',
|
|
29
|
+
data: {
|
|
30
|
+
'address-form-target': 'country',
|
|
31
|
+
'action': "change->address-form#changeCountry"
|
|
32
|
+
},
|
|
33
|
+
aria: { label: Spree.t(:country) } } %>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
<% elsif field == "state" %>
|
|
38
|
+
<div class="form-group mb-4 address-form">
|
|
39
|
+
<%= address_field(address_form, :state, address_id) { address_state(address_form, address.country, address_id) } if Spree::Config[:address_requires_state] %>
|
|
40
|
+
</div>
|
|
41
|
+
<% elsif field == "zipcode" %>
|
|
42
|
+
<div class="form-group mb-4">
|
|
43
|
+
<%= address_field(address_form, :zipcode, address_id) { address_zipcode(address_form, address.country, address_id) } %>
|
|
44
|
+
</div>
|
|
45
|
+
<% else %>
|
|
46
|
+
<% next if field == "company" && !Spree::Config[:company] %>
|
|
47
|
+
<% next if field == "alternative_#{address_id}_phone" && !Spree::Config["alternative_#{address_id}_phone"] %>
|
|
48
|
+
<div class="form-group mb-4">
|
|
49
|
+
<%= address_field(address_form, field.to_sym, address_id) %>
|
|
50
|
+
</div>
|
|
51
|
+
<% end %>
|
|
52
|
+
<% end %>
|
|
53
|
+
|
|
54
|
+
<p class="text-right mb-5 checkout-content-inner-field"><span id="required_marker"><%= Spree.t(:required) %></span> <%= Spree.t(:required_fields) %></p>
|
|
55
|
+
</div>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<% s_or_b = type.chars.first %>
|
|
2
|
+
|
|
3
|
+
<div id="<%= type %>" data-hook="address_fields">
|
|
4
|
+
<% order_address_fields(Spree::Address::ADDRESS_FIELDS).each do |field| %>
|
|
5
|
+
<% if field == "country" %>
|
|
6
|
+
<%= field_container (s_or_b + '_' + field), nil, class: ["#{type}-row"] do %>
|
|
7
|
+
<%= f.label :country_id, Spree.t(:country) %>
|
|
8
|
+
<div id="<%= s_or_b %>country">
|
|
9
|
+
<%= f.collection_select :country_id, all_countries, :id, :name, {}, { class: 'select2 w-100' } %>
|
|
10
|
+
</div>
|
|
11
|
+
<% end %>
|
|
12
|
+
<% elsif field == "state" %>
|
|
13
|
+
<%= field_container (s_or_b + '_' + field), :state, class: ["#{type}-row"] do %>
|
|
14
|
+
<%= f.label :state_id, Spree.t(:state) %>
|
|
15
|
+
<div id="<%= s_or_b %>state">
|
|
16
|
+
<% if f.object.country.try(:states) %>
|
|
17
|
+
<%= f.text_field :state_name,
|
|
18
|
+
style: "display: #{f.object.country.try(:states) && f.object.country.states.empty? ? 'block' : 'none' };",
|
|
19
|
+
disabled: !(f.object.country.try(:states) && f.object.country.states.empty?), class: 'form-control state_name' %>
|
|
20
|
+
<%= f.collection_select :state_id, f.object.country.states.sort, :id, :name, { include_blank: true }, { class: 'select2 w-100', disabled: f.object.country.states.empty? } %>
|
|
21
|
+
<% else %>
|
|
22
|
+
<div>
|
|
23
|
+
<em><%= Spree.t(:no_country) %></em>
|
|
24
|
+
</div>
|
|
25
|
+
<% end %>
|
|
26
|
+
</div>
|
|
27
|
+
<%= error_message_on f.object, :state_id %>
|
|
28
|
+
<% end %>
|
|
29
|
+
<% else %>
|
|
30
|
+
<%= field_container (s_or_b + '_' + field), nil, class: ["#{type}-row"] do %>
|
|
31
|
+
<%= f.label field, Spree.t(field) %>
|
|
32
|
+
<%= f.text_field field, class: 'form-control' %>
|
|
33
|
+
<%= error_message_on f.object, field %>
|
|
34
|
+
<% end %>
|
|
35
|
+
<% end %>
|
|
36
|
+
<% end %>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<% content_for :head do %>
|
|
40
|
+
<script>
|
|
41
|
+
document.addEventListener("spree:load", function() {
|
|
42
|
+
$('#<%= s_or_b %>country select').on('change', function() { updateAddressState('<%= s_or_b %>'); });
|
|
43
|
+
})
|
|
44
|
+
</script>
|
|
45
|
+
<% end %>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="card mb-4">
|
|
2
|
+
<div class="card-header">
|
|
3
|
+
<h5 class="card-title"><%= Spree.t(:address_field_settings) %></h5>
|
|
4
|
+
</div>
|
|
5
|
+
<div class="card-body">
|
|
6
|
+
<%= f.spree_check_box :show_country_field, label: Spree.t(:show_country_field) %>
|
|
7
|
+
<%= f.spree_check_box :use_kana_fields, label: Spree.t(:use_kana_fields) %>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
data/bin/rails
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" from the root of your extension
|
|
3
|
+
|
|
4
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
5
|
+
ENGINE_PATH = File.expand_path('../../lib/spree_address_format_i18n/engine', __FILE__)
|
|
6
|
+
|
|
7
|
+
require 'rails/all'
|
|
8
|
+
require 'rails/engine/commands'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
ja:
|
|
2
|
+
spree:
|
|
3
|
+
lastname_kana: セイ
|
|
4
|
+
firstname_kana: メイ
|
|
5
|
+
fax: FAX
|
|
6
|
+
company_kana: カナ会社名
|
|
7
|
+
use_kana_fields: "住所にかなフィールドを使用する"
|
|
8
|
+
show_country_field: "住所に国フィールドを表示する"
|
|
9
|
+
address_field_settings: "住所フィールド設定"
|
|
10
|
+
internationalization: "国際化"
|
|
11
|
+
activerecord:
|
|
12
|
+
attributes:
|
|
13
|
+
spree/address:
|
|
14
|
+
lastname_kana: セイ
|
|
15
|
+
firstname_kana: メイ
|
|
16
|
+
company_kana: カナ会社名
|
|
17
|
+
fax: FAX
|
|
18
|
+
spree/order/bill_address:
|
|
19
|
+
lastname_kana: セイ
|
|
20
|
+
firstname_kana: メイ
|
|
21
|
+
company_kana: カナ会社名
|
|
22
|
+
fax: FAX
|
|
23
|
+
spree/order/ship_address:
|
|
24
|
+
lastname_kana: セイ
|
|
25
|
+
firstname_kana: メイ
|
|
26
|
+
company_kana: カナ会社名
|
|
27
|
+
fax: FAX
|