-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add organization structured data fields to Spree stores for SEO
- Added new fields to spree_stores to support organization structured data for SEO. - Fields include legal_name, contact_email, contact_phone, description, vat_id, tax_id, address1, address2, city, zipcode, state_name, country_id, and state_id. - This update enhances SEO by allowing structured data markup for better search engine visibility. Enhance store API schema with additional attributes Updated the API schema for store-related endpoints to include additional store attributes. Update admin view for store new and edit form - Added component for rendering the store edit and new views. - Added address partial as a separate component within the store form. - Added the test cases for new, edit and address form component
- Loading branch information
1 parent
cc2f7cb
commit bbff7bc
Showing
24 changed files
with
919 additions
and
11 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
admin/app/components/solidus_admin/stores/address_form/component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<fieldset class="<%= stimulus_id %>" | ||
data-controller="<%= stimulus_id %>" | ||
> | ||
<div class="<%= stimulus_id %>--address-form flex flex-wrap gap-4 pb-4"> | ||
<%= render component("ui/forms/field").text_field(@name, :legal_name, object: @store) %> | ||
<%= render component("ui/forms/field").text_field(@name, :address1, object: @store) %> | ||
<%= render component("ui/forms/field").text_field(@name, :address2, object: @store) %> | ||
<div class="flex gap-4 w-full"> | ||
<%= render component("ui/forms/field").text_field(@name, :city, object: @store) %> | ||
<%= render component("ui/forms/field").text_field(@name, :zipcode, object: @store) %> | ||
</div> | ||
|
||
<%= render component("ui/forms/field").select( | ||
@name, | ||
:country_id, | ||
Spree::Country.pluck(:name, :id), | ||
object: @store, | ||
value: @store.country_id, | ||
"data-#{stimulus_id}-target": "country", | ||
"data-action": "change->#{stimulus_id}#loadStates" | ||
) %> | ||
|
||
<%= content_tag :div, | ||
class: "flex flex-col gap-2 w-full #{'hidden' unless @store.country&.states_required}", | ||
data: { "#{stimulus_id}-target": "stateNameWrapper" } do %> | ||
<%= render component("ui/forms/field").text_field( | ||
@name, :state_name, | ||
object: @store, | ||
value: @store.state_name, | ||
data: { "#{stimulus_id}-target": "stateName" } | ||
) %> | ||
<% end %> | ||
|
||
<input autocomplete="off" type="hidden" name=<%= "#{@name}[state_id]" %>> | ||
|
||
<%= content_tag :div, | ||
class: "flex flex-col gap-2 w-full #{'hidden' if @store.country&.states_required}", | ||
data: { "#{stimulus_id}-target": "stateWrapper" } do %> | ||
<%= render component("ui/forms/field").select( | ||
@name, :state_id, | ||
state_options, | ||
object: @store, | ||
value: @store.state_id, | ||
data: { "#{stimulus_id}-target": "state" } | ||
) %> | ||
<% end %> | ||
|
||
<%= render component("ui/forms/field").text_field(@name, :contact_phone, object: @store) %> | ||
</div> | ||
</fieldset> |
56 changes: 56 additions & 0 deletions
56
admin/app/components/solidus_admin/stores/address_form/component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { Controller } from "@hotwired/stimulus" | ||
|
||
export default class extends Controller { | ||
static targets = ["country", "state", "stateName", "stateWrapper", "stateNameWrapper"] | ||
|
||
loadStates() { | ||
const countryId = this.countryTarget.value | ||
|
||
fetch(`/admin/countries/${countryId}/states`) | ||
.then((response) => response.json()) | ||
.then((data) => { | ||
this.updateStateOptions(data) | ||
}) | ||
} | ||
|
||
updateStateOptions(states) { | ||
if (states.length === 0) { | ||
this.toggleStateFields(false) | ||
} else { | ||
this.toggleStateFields(true) | ||
this.populateStateSelect(states) | ||
} | ||
} | ||
|
||
toggleStateFields(showSelect) { | ||
const stateWrapper = this.stateWrapperTarget | ||
const stateNameWrapper = this.stateNameWrapperTarget | ||
const stateSelect = this.stateTarget | ||
const stateName = this.stateNameTarget | ||
|
||
if (showSelect) { | ||
// Show state select dropdown. | ||
stateSelect.disabled = false | ||
stateName.value = "" | ||
stateWrapper.classList.remove("hidden") | ||
stateNameWrapper.classList.add("hidden") | ||
} else { | ||
// Show state name text input if no states to choose from. | ||
stateSelect.disabled = true | ||
stateWrapper.classList.add("hidden") | ||
stateNameWrapper.classList.remove("hidden") | ||
} | ||
} | ||
|
||
populateStateSelect(states) { | ||
const stateSelect = this.stateTarget | ||
stateSelect.innerHTML = "" | ||
|
||
states.forEach((state) => { | ||
const option = document.createElement("option") | ||
option.value = state.id | ||
option.innerText = state.name | ||
stateSelect.appendChild(option) | ||
}) | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
admin/app/components/solidus_admin/stores/address_form/component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
class SolidusAdmin::Stores::AddressForm::Component < SolidusAdmin::BaseComponent | ||
def initialize(store:) | ||
@name = "store" | ||
@store = store | ||
end | ||
|
||
def state_options | ||
country = @store.country | ||
return [] unless country && country.states_required | ||
|
||
country.states.pluck(:name, :id) | ||
end | ||
end |
65 changes: 65 additions & 0 deletions
65
admin/app/components/solidus_admin/stores/edit/component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<%= page do %> | ||
<%= page_header do %> | ||
<%= page_header_back(solidus_admin.stores_path) %> | ||
<%= page_header_title(t(".title", store: @store&.name)) %> | ||
<% end %> | ||
|
||
<%= form_for @store, url: solidus_admin.store_path(@store), html: { id: form_id } do |f| %> | ||
<%= page_with_sidebar do %> | ||
<%= page_with_sidebar_main do %> | ||
<%= render component("ui/panel").new(title: t(".store_details")) do %> | ||
<div class="flex flex-wrap gap-4 pb-4"> | ||
<%= render component("ui/forms/field").text_field(f, :name, required: true) %> | ||
<%= render component("ui/forms/field").text_field(f, :code, required: true) %> | ||
<%= render component("ui/forms/field").text_field(f, :seo_title) %> | ||
<%= render component("ui/forms/field").text_field(f, :meta_keywords) %> | ||
<%= render component("ui/forms/field").text_area(f, :meta_description) %> | ||
<%= render component("ui/forms/field").text_field(f, :tax_id) %> | ||
<%= render component("ui/forms/field").text_field(f, :vat_id) %> | ||
<%= render component("ui/forms/field").text_field(f, :url, required: true) %> | ||
<%= render component("ui/forms/field").text_field(f, :mail_from_address, required: true) %> | ||
<%= render component("ui/forms/field").text_field(f, :bcc_email) %> | ||
<%= render component("ui/forms/field").select( | ||
f, | ||
:default_currency, | ||
currency_options, | ||
include_blank: true | ||
) %> | ||
<%= render component("ui/forms/field").select( | ||
f, | ||
:cart_tax_country_iso, | ||
cart_tax_country_options, | ||
include_blank: t(".no_cart_tax_country") | ||
) %> | ||
<%= render component("ui/forms/field").select( | ||
f, | ||
:available_locales, | ||
localization_options, | ||
multiple: true, | ||
class: "select2", | ||
name: "store[available_locales][]" | ||
) %> | ||
</div> | ||
<%= render component("ui/forms/field").text_area(f, :description) %> | ||
<% end %> | ||
|
||
<%= render component("ui/panel").new(title: t(".address")) do %> | ||
<div class="js-addresses-form"> | ||
<%= render component("stores/address_form").new( | ||
store: @store, | ||
) %> | ||
</div> | ||
<% end %> | ||
<% end %> | ||
<% end %> | ||
<% end %> | ||
|
||
<%= page_footer do %> | ||
<%= page_footer_actions do %> | ||
<div class="py-1.5 text-center"> | ||
<%= render component("ui/button").new(tag: :button, text: t(".update"), form: form_id) %> | ||
<%= render component("ui/button").new(tag: :a, text: t(".cancel"), href: solidus_admin.edit_store_path(@store), scheme: :secondary) %> | ||
</div> | ||
<% end %> | ||
<% end %> | ||
<% end %> |
62 changes: 62 additions & 0 deletions
62
admin/app/components/solidus_admin/stores/edit/component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# frozen_string_literal: true | ||
|
||
class SolidusAdmin::Stores::Edit::Component < SolidusAdmin::BaseComponent | ||
include SolidusAdmin::Layout::PageHelpers | ||
|
||
# Define the necessary attributes for the component | ||
attr_reader :store, :available_countries | ||
|
||
# Initialize the component with required data | ||
def initialize(store:) | ||
@store = store | ||
@available_countries = fetch_available_countries | ||
end | ||
|
||
def form_id | ||
@form_id ||= "#{stimulus_id}--form-#{@store.id}" | ||
end | ||
|
||
def currency_options | ||
Spree::Config.available_currencies.map(&:iso_code) | ||
end | ||
|
||
# Generates options for cart tax countries | ||
def cart_tax_country_options | ||
fetch_available_countries(restrict_to_zone: Spree::Config[:checkout_zone]).map do |country| | ||
[country.name, country.iso] | ||
end | ||
end | ||
|
||
# Generates available locales | ||
def localization_options | ||
Spree.i18n_available_locales.map do |locale| | ||
[ | ||
I18n.t('spree.i18n.this_file_language', locale: locale, default: locale.to_s), | ||
locale | ||
] | ||
end | ||
end | ||
|
||
# Fetch countries for the address form | ||
def available_country_options | ||
Spree::Country.order(:name).map { |country| [country.name, country.id] } | ||
end | ||
|
||
private | ||
|
||
# Fetch the available countries for the localization section | ||
def fetch_available_countries(restrict_to_zone: Spree::Config[:checkout_zone]) | ||
countries = Spree::Country.available(restrict_to_zone:) | ||
|
||
country_names = Carmen::Country.all.map do |country| | ||
[country.code, country.name] | ||
end.to_h | ||
|
||
country_names.update I18n.t('spree.country_names', default: {}).stringify_keys | ||
|
||
countries.collect do |country| | ||
country.name = country_names.fetch(country.iso, country.name) | ||
country | ||
end.sort_by { |country| country.name.parameterize } | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
en: | ||
title: "%{store}" | ||
store_details: Store Details | ||
address: Address | ||
update: Update | ||
cancel: Cancel |
65 changes: 65 additions & 0 deletions
65
admin/app/components/solidus_admin/stores/new/component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<%= page do %> | ||
<%= page_header do %> | ||
<%= page_header_back(solidus_admin.stores_path) %> | ||
<%= page_header_title(t(".title")) %> | ||
<% end %> | ||
|
||
<%= form_for @store, url: solidus_admin.stores_path, html: { id: form_id } do |f| %> | ||
<%= page_with_sidebar do %> | ||
<%= page_with_sidebar_main do %> | ||
<%= render component("ui/panel").new(title: t(".store_details")) do %> | ||
<div class="flex flex-wrap gap-4 pb-4"> | ||
<%= render component("ui/forms/field").text_field(f, :name, required: true) %> | ||
<%= render component("ui/forms/field").text_field(f, :code, required: true) %> | ||
<%= render component("ui/forms/field").text_field(f, :seo_title) %> | ||
<%= render component("ui/forms/field").text_field(f, :meta_keywords) %> | ||
<%= render component("ui/forms/field").text_area(f, :meta_description) %> | ||
<%= render component("ui/forms/field").text_field(f, :tax_id) %> | ||
<%= render component("ui/forms/field").text_field(f, :vat_id) %> | ||
<%= render component("ui/forms/field").text_field(f, :url, required: true) %> | ||
<%= render component("ui/forms/field").text_field(f, :mail_from_address, required: true) %> | ||
<%= render component("ui/forms/field").text_field(f, :bcc_email) %> | ||
<%= render component("ui/forms/field").select( | ||
f, | ||
:default_currency, | ||
currency_options, | ||
include_blank: true | ||
) %> | ||
<%= render component("ui/forms/field").select( | ||
f, | ||
:cart_tax_country_iso, | ||
cart_tax_country_options, | ||
include_blank: t(".no_cart_tax_country") | ||
) %> | ||
<%= render component("ui/forms/field").select( | ||
f, | ||
:available_locales, | ||
localization_options, | ||
multiple: true, | ||
class: "select2", | ||
name: "store[available_locales][]" | ||
) %> | ||
</div> | ||
<%= render component("ui/forms/field").text_area(f, :description) %> | ||
<% end %> | ||
|
||
<%= render component("ui/panel").new(title: t(".address")) do %> | ||
<div class="js-addresses-form"> | ||
<%= render component("stores/address_form").new( | ||
store: @store, | ||
) %> | ||
</div> | ||
<% end %> | ||
<% end %> | ||
<% end %> | ||
<% end %> | ||
|
||
<%= page_footer do %> | ||
<%= page_footer_actions do %> | ||
<div class="py-1.5 text-center"> | ||
<%= render component("ui/button").new(tag: :button, text: t(".save"), form: form_id) %> | ||
<%= render component("ui/button").new(tag: :a, text: t(".cancel"), href: solidus_admin.new_store_path, scheme: :secondary) %> | ||
</div> | ||
<% end %> | ||
<% end %> | ||
<% end %> |
62 changes: 62 additions & 0 deletions
62
admin/app/components/solidus_admin/stores/new/component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# frozen_string_literal: true | ||
|
||
class SolidusAdmin::Stores::New::Component < SolidusAdmin::BaseComponent | ||
include SolidusAdmin::Layout::PageHelpers | ||
|
||
# Define the necessary attributes for the component | ||
attr_reader :store, :available_countries | ||
|
||
# Initialize the component with required data | ||
def initialize(store:) | ||
@store = store | ||
@available_countries = fetch_available_countries | ||
end | ||
|
||
def form_id | ||
@form_id ||= "#{stimulus_id}--form-#{@store.id}" | ||
end | ||
|
||
def currency_options | ||
Spree::Config.available_currencies.map(&:iso_code) | ||
end | ||
|
||
# Generates options for cart tax countries | ||
def cart_tax_country_options | ||
fetch_available_countries(restrict_to_zone: Spree::Config[:checkout_zone]).map do |country| | ||
[country.name, country.iso] | ||
end | ||
end | ||
|
||
# Generates available locales | ||
def localization_options | ||
Spree.i18n_available_locales.map do |locale| | ||
[ | ||
I18n.t('spree.i18n.this_file_language', locale: locale, default: locale.to_s), | ||
locale | ||
] | ||
end | ||
end | ||
|
||
# Fetch countries for the address form | ||
def available_country_options | ||
Spree::Country.order(:name).map { |country| [country.name, country.id] } | ||
end | ||
|
||
private | ||
|
||
# Fetch the available countries for the localization section | ||
def fetch_available_countries(restrict_to_zone: Spree::Config[:checkout_zone]) | ||
countries = Spree::Country.available(restrict_to_zone:) | ||
|
||
country_names = Carmen::Country.all.map do |country| | ||
[country.code, country.name] | ||
end.to_h | ||
|
||
country_names.update I18n.t('spree.country_names', default: {}).stringify_keys | ||
|
||
countries.collect do |country| | ||
country.name = country_names.fetch(country.iso, country.name) | ||
country | ||
end.sort_by { |country| country.name.parameterize } | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
en: | ||
title: "New Store" | ||
save: Save | ||
store_details: Store Details | ||
address: Address | ||
cancel: Cancel |
Oops, something went wrong.