feat: add sitemap for help center (#9280)
* feat: start sitemap * feat: add base url and last mod to sitemap * fix: typo * test: sitemap generation * test: add draft articles * fix: escape dots in regex matching * feat: perpend protocol to the url * feat: use ChatwootApp.help_center_root * feat: don't parse the URL * fix: function declaration
This commit is contained in:
@@ -6,6 +6,12 @@ class Public::Api::V1::PortalsController < Public::Api::V1::Portals::BaseControl
|
|||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
|
def sitemap
|
||||||
|
@help_center_url = @portal.custom_domain || ChatwootApp.help_center_root
|
||||||
|
# if help_center_url does not contain a protocol, prepend it with https
|
||||||
|
@help_center_url = "https://#{@help_center_url}" unless @help_center_url.include?('://')
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def portal
|
def portal
|
||||||
|
|||||||
9
app/views/public/api/v1/portals/sitemap.xml.erb
Normal file
9
app/views/public/api/v1/portals/sitemap.xml.erb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sitemapindex>
|
||||||
|
<% @portal.articles.where(status: :published).each do |article| %>
|
||||||
|
<sitemap>
|
||||||
|
<loc><%= @help_center_url %><%= generate_article_link(@portal.slug, article.slug, false, false) %></loc>
|
||||||
|
<lastmod><%= article.updated_at.strftime("%Y-%m-%d") %></lastmod>
|
||||||
|
</sitemap>
|
||||||
|
<% end %>
|
||||||
|
</sitemapindex>
|
||||||
@@ -393,6 +393,7 @@ Rails.application.routes.draw do
|
|||||||
end
|
end
|
||||||
|
|
||||||
get 'hc/:slug', to: 'public/api/v1/portals#show'
|
get 'hc/:slug', to: 'public/api/v1/portals#show'
|
||||||
|
get 'hc/:slug/sitemap.xml', to: 'public/api/v1/portals#sitemap'
|
||||||
get 'hc/:slug/:locale', to: 'public/api/v1/portals#show'
|
get 'hc/:slug/:locale', to: 'public/api/v1/portals#show'
|
||||||
get 'hc/:slug/:locale/articles', to: 'public/api/v1/portals/articles#index'
|
get 'hc/:slug/:locale/articles', to: 'public/api/v1/portals/articles#index'
|
||||||
get 'hc/:slug/:locale/categories', to: 'public/api/v1/portals/categories#index'
|
get 'hc/:slug/:locale/categories', to: 'public/api/v1/portals/categories#index'
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ module ChatwootApp
|
|||||||
@custom ||= root.join('custom').exist?
|
@custom ||= root.join('custom').exist?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.help_center_root
|
||||||
|
ENV.fetch('HELPCENTER_URL', nil) || ENV.fetch('FRONTEND_URL', nil)
|
||||||
|
end
|
||||||
|
|
||||||
def self.extensions
|
def self.extensions
|
||||||
if custom?
|
if custom?
|
||||||
%w[enterprise custom]
|
%w[enterprise custom]
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe 'Public Portals API', type: :request do
|
RSpec.describe Public::Api::V1::PortalsController, type: :request do
|
||||||
let!(:account) { create(:account) }
|
let!(:account) { create(:account) }
|
||||||
|
let!(:agent) { create(:user, account: account, role: :agent) }
|
||||||
let!(:portal) { create(:portal, slug: 'test-portal', account_id: account.id, custom_domain: 'www.example.com') }
|
let!(:portal) { create(:portal, slug: 'test-portal', account_id: account.id, custom_domain: 'www.example.com') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
create(:portal, slug: 'test-portal-1', account_id: account.id)
|
create(:portal, slug: 'test-portal-1', account_id: account.id)
|
||||||
create(:portal, slug: 'test-portal-2', account_id: account.id)
|
create(:portal, slug: 'test-portal-2', account_id: account.id)
|
||||||
|
create_list(:article, 3, account: account, author: agent, portal: portal, status: :published)
|
||||||
|
create_list(:article, 2, account: account, author: agent, portal: portal, status: :draft)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET /public/api/v1/portals/{portal_slug}' do
|
describe 'GET /public/api/v1/portals/{portal_slug}' do
|
||||||
@@ -28,4 +31,28 @@ RSpec.describe 'Public Portals API', type: :request do
|
|||||||
Please send us an email at support@chatwoot.com with the custom domain name and account API key"
|
Please send us an email at support@chatwoot.com with the custom domain name and account API key"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'GET /public/api/v1/portals/{portal_slug}/sitemap' do
|
||||||
|
context 'when custom_domain is present' do
|
||||||
|
it 'gets a valid sitemap' do
|
||||||
|
get "/hc/#{portal.slug}/sitemap.xml"
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(response.body).to match(/<sitemap/)
|
||||||
|
expect(Nokogiri::XML(response.body).errors).to be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has valid sitemap links' do
|
||||||
|
get "/hc/#{portal.slug}/sitemap.xml"
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
parsed_xml = Nokogiri::XML(response.body)
|
||||||
|
links = parsed_xml.css('loc')
|
||||||
|
|
||||||
|
links.each do |link|
|
||||||
|
expect(link.text).to match(%r{https://www\.example\.com/hc/test-portal/articles/\d+})
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(links.length).to eq 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user