diff --git a/app/components/access_panels/other_listings_component.html.erb b/app/components/access_panels/other_listings_component.html.erb
new file mode 100644
index 000000000..f11b4ce6d
--- /dev/null
+++ b/app/components/access_panels/other_listings_component.html.erb
@@ -0,0 +1,11 @@
+<%= render @layout.new do |component| %>
+ <% component.with_title { 'Also listed in' } %>
+ <% component.with_body do %>
+ <% if earthworks_url.present? %>
+
<%= link_to('Earthworks', earthworks_url) %>
+ <% end %>
+ <% purl_links.each do |purl_link| %>
+ <%= purl_link %>
+ <% end %>
+ <% end %>
+<% end %>
diff --git a/app/components/access_panels/other_listings_component.rb b/app/components/access_panels/other_listings_component.rb
new file mode 100644
index 000000000..f2ba6e1d8
--- /dev/null
+++ b/app/components/access_panels/other_listings_component.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module AccessPanels
+ class OtherListingsComponent < AccessPanels::Base
+ def render?
+ earthworks_url.present? || purls.present?
+ end
+
+ def earthworks_url
+ @earthworks_url ||= construct_earthworks_url
+ end
+
+ # @return [Array] a tags representing PURL links
+ def purl_links
+ @purl_links ||=
+ if purls.size > 1 # text of the link is the actual URL if there is more than one unique URL, so there aren't multiple links with the same title
+ purls.map { |purl| link_to(purl, purl) }
+ elsif purls.size == 1
+ Array(link_to('Stanford Digital Repository', purls.first))
+ else
+ []
+ end
+ end
+
+ private
+
+ # @return [Array] URLs representing links to PURL, whether specified in MARC or MODS, and de-duped, e.g. ["https://purl.stanford.edu/hj948rn6493"]
+ def purls
+ @purls ||= (mods_purls + marc_managed_purls).uniq
+ end
+
+ # @return [Array] URLs representing links to other locations, extracted from MODS metadata, e.g. ["https://purl.stanford.edu/hj948rn6493"]
+ def mods_purls
+ Array(document['url_fulltext']).find_all { |str| str.start_with?(Settings.PURL_EMBED_RESOURCE) }
+ end
+
+ # @return [Array] URLs representing links to other locations, extracted from MARC metadata, e.g. ["https://purl.stanford.edu/hj948rn6493"]
+ def marc_managed_purls
+ document.marc_links.managed_purls.filter_map(&:href) # filter_map because href can be nil, at least in fixture data
+ end
+
+ def construct_earthworks_url
+ return nil unless document['dor_content_type_ssi'] == 'geo'
+
+ # * Hardcoding this simple URL format because it should work for all things it'd apply to (anything released to both SW and EW should be a Stanford object)
+ # * Using Kernel.format because there's a clashing ViewComponent::Base#format, so the namespacing is needed
+ Kernel.format('https://%s/catalog/stanford-%s', hostname: Settings.earthworks.hostname, bare_druid: document.druid)
+ end
+ end
+end
diff --git a/app/views/catalog/record/_metadata_panels.html.erb b/app/views/catalog/record/_metadata_panels.html.erb
index 72d01f26e..31e69a43c 100644
--- a/app/views/catalog/record/_metadata_panels.html.erb
+++ b/app/views/catalog/record/_metadata_panels.html.erb
@@ -11,6 +11,7 @@
<% potential_context = capture do %>
<%= render AccessPanels::ExhibitComponent.new(document: document) %>
+ <%= render AccessPanels::OtherListingsComponent.new(document: document) %>
<% end %>
<% if context.present? || potential_context.present? %>
diff --git a/app/views/catalog/record/_mods_bibliographic.html.erb b/app/views/catalog/record/_mods_bibliographic.html.erb
index 211f527e6..ac67491cd 100644
--- a/app/views/catalog/record/_mods_bibliographic.html.erb
+++ b/app/views/catalog/record/_mods_bibliographic.html.erb
@@ -24,6 +24,6 @@
<%= render ModsDisplay::FieldComponent.new(field: identifier, label_html_attributes: { class: 'col-md-3' }, value_html_attributes: { class: 'col-md-9' }) %>
<% end %>
-<% document.mods.location.each do |location| %>
+<% document.mods.location.reject { |location| location.values.detect { |loc| /href=.#{Settings.PURL_EMBED_RESOURCE}/.match?(loc) } }.each do |location| %>
<%= render ModsDisplay::FieldComponent.new(field: location, label_html_attributes: { class: 'col-md-3' }, value_html_attributes: { class: 'col-md-9' }) %>
<% end %>
diff --git a/config/settings.yml b/config/settings.yml
index 780779c39..cc3b79556 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -275,3 +275,6 @@ folio_unrequestable_statuses:
- Unavailable
- Unknown
- Withdrawn
+
+earthworks:
+ hostname: 'earthworks.stanford.edu'
diff --git a/spec/components/access_panels/other_listings_component_spec.rb b/spec/components/access_panels/other_listings_component_spec.rb
new file mode 100644
index 000000000..3123f94d2
--- /dev/null
+++ b/spec/components/access_panels/other_listings_component_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe AccessPanels::OtherListingsComponent, type: :component do
+ include MarcMetadataFixtures
+
+ let(:component) { described_class.new(document:) }
+
+ let(:document_hash) { { id: '123', dor_content_type_ssi: 'notgeo' } }
+ let(:document) { SolrDocument.new(document_hash) }
+
+ subject(:page) { render_inline(component) }
+
+ it 'does not render if the item neither is released to Earthworks nor has a PURL' do
+ page
+ expect(rendered_content).to eq ""
+ end
+
+ context 'there is a PURL specified in the MARC' do
+ let(:document_hash) do
+ {
+ id: 'hj948rn6493',
+ marc_links_struct: [
+ { href: 'https://purl.stanford.edu/hj948rn6493', managed_purl: true }
+ ]
+ }
+ end
+
+ it 'displays a link to the PURL' do
+ expect(page).to have_link('Stanford Digital Repository', href: 'https://purl.stanford.edu/hj948rn6493')
+ end
+ end
+
+ context 'there is a PURL specified in the MODS' do
+ let(:document_hash) { { id: 'bd285ct9109', url_fulltext: 'https://purl.stanford.edu/hj948rn6493' } }
+
+ it 'displays a link to the PURL' do
+ expect(page).to have_link('Stanford Digital Repository', href: 'https://purl.stanford.edu/hj948rn6493')
+ end
+ end
+
+ context 'the same PURL is specified in both MARC and MODS' do
+ let(:document_hash) do
+ {
+ id: 'hj948rn6493',
+ url_fulltext: 'https://purl.stanford.edu/hj948rn6493',
+ marc_links_struct: [
+ { href: 'https://purl.stanford.edu/hj948rn6493', managed_purl: true }
+ ]
+ }
+ end
+
+ it 'displays a single link to the PURL' do
+ expect(page).to have_link('Stanford Digital Repository', href: 'https://purl.stanford.edu/hj948rn6493')
+ expect(page).to have_css('a', count: 1)
+ end
+ end
+
+ context 'MODS and MARC specify different PURLs' do
+ let(:document_hash) do
+ {
+ id: '123',
+ url_fulltext: 'https://purl.stanford.edu/bc123df4567',
+ marc_links_struct: [
+ { href: 'https://purl.stanford.edu/gh890jk9876', managed_purl: true }
+ ]
+ }
+ end
+
+ it 'displays a single link to the PURL' do
+ expect(page).to have_link('https://purl.stanford.edu/bc123df4567', href: 'https://purl.stanford.edu/bc123df4567')
+ expect(page).to have_link('https://purl.stanford.edu/gh890jk9876', href: 'https://purl.stanford.edu/gh890jk9876')
+ expect(page).to have_css('a', count: 2)
+ end
+ end
+
+ context 'the object has been released to Earthworks' do
+ let(:document_hash) { { id: 'bd285ct9109', druid: 'bd285ct9109', dor_content_type_ssi: 'geo' } }
+
+ it 'displays a link to Earthworks' do
+ expect(page).to have_link('Earthworks', href: "https://#{Settings.earthworks.hostname}/catalog/stanford-bd285ct9109")
+ end
+ end
+
+ context 'the object has been released to Earthworks and it has a PURL' do
+ let(:document_hash) { { druid: 'bd285ct9109', url_fulltext: 'https://purl.stanford.edu/bd285ct9109', dor_content_type_ssi: 'geo' } }
+
+ it 'displays a link to the PURL and a link to Earthworks' do
+ expect(page).to have_link('Stanford Digital Repository', href: 'https://purl.stanford.edu/bd285ct9109')
+ expect(page).to have_link('Earthworks', href: "https://#{Settings.earthworks.hostname}/catalog/stanford-bd285ct9109")
+ end
+ end
+end